Facebook Pixel

2801. Count Stepping Numbers in Range

Problem Description

You are given two positive integers low and high represented as strings. Your task is to find the count of stepping numbers in the inclusive range [low, high].

A stepping number is an integer where all adjacent digits have an absolute difference of exactly 1. For example:

  • 12 is a stepping number because |1-2| = 1
  • 321 is a stepping number because |3-2| = 1 and |2-1| = 1
  • 13 is NOT a stepping number because |1-3| = 2

Important constraints:

  • Stepping numbers should not have leading zeros
  • Since the answer may be very large, return it modulo 10^9 + 7

The solution uses a digit dynamic programming approach. The key idea is to break down the problem into two parts: counting stepping numbers from 1 to high and from 1 to low-1, then finding the difference.

The dfs function tracks:

  • pos: Current digit position being processed
  • pre: Previous digit value (or -1 if no previous digit)
  • lead: Whether we're still in leading zeros
  • limit: Whether we're bounded by the upper limit of the current number

For each position, we try placing digits 0 to 9 (or up to the limit), ensuring that:

  1. If we're placing a non-zero digit or we're past leading zeros, the absolute difference with the previous digit must be exactly 1
  2. We properly handle leading zeros (they don't count as part of the stepping number check)

The algorithm calculates stepping numbers up to high, then subtracts the count of stepping numbers up to low-1 to get the final answer for the range [low, high].

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

When faced with counting problems over a large range of numbers, especially when the constraint involves relationships between digits (like adjacent digits differing by exactly 1), we should think about digit dynamic programming.

The key insight is that we can build valid stepping numbers digit by digit from left to right. At each position, we only need to know what the previous digit was to determine what valid choices we have for the current digit. If the previous digit was 5, we can only place 4 or 6 next. This local constraint makes the problem perfect for dynamic programming.

Why can't we just iterate through all numbers from low to high? The range could be enormous (up to 10^100 or more since they're given as strings), making direct enumeration impossible.

The standard technique for range queries [L, R] is to transform it into count(R) - count(L-1). This way, we only need to solve the problem of counting stepping numbers from 0 up to some value N.

For the digit DP approach, we process the number digit by digit. The crucial observation is that we need to track:

  • Whether we're still bounded by the original number (if we've placed a smaller digit earlier, we're free to place any valid digit now)
  • Whether we're still in the leading zeros phase (leading zeros don't count for the stepping number property)
  • What the previous digit was (to enforce the stepping constraint)

The beauty of this approach is that it explores only valid paths through the digit choices, avoiding the need to check every number in the potentially massive range. By memoizing our recursive calls, we ensure that each unique state (position, previous_digit, has_leading_zeros, is_limited) is computed only once, giving us an efficient solution.

Learn more about Dynamic Programming patterns.

Solution Approach

The solution implements digit DP using a recursive function with memoization. Let's walk through the implementation step by step:

Core Function: dfs(pos, pre, lead, limit)

The function parameters represent:

  • pos: Current position in the number string (0-indexed from left)
  • pre: Previous digit placed (-1 if no digit placed yet)
  • lead: Boolean indicating if we're still in leading zeros
  • limit: Boolean indicating if we must respect the upper bound of the original number

Base Case

if pos >= len(num):
    return int(not lead)

When we've processed all positions, we return 1 if we've formed a valid number (not all leading zeros), otherwise 0.

Recursive Case

First, we determine the upper bound for the current digit:

up = int(num[pos]) if limit else 9

If limit is True, we can only go up to the digit at position pos in the original number. Otherwise, we can use any digit from 0 to 9.

Then we enumerate all possible digits for the current position:

for i in range(up + 1):

For each digit i, we have two cases:

Case 1: Leading Zero

if i == 0 and lead:
    ans += dfs(pos + 1, pre, True, limit and i == up)

If we place a 0 and we're still in the leading zeros phase, we continue with leading zeros. The pre remains unchanged since this zero doesn't count as part of the number.

Case 2: Valid Stepping Digit

elif pre == -1 or abs(i - pre) == 1:
    ans += dfs(pos + 1, i, False, limit and i == up)

We can place digit i if:

  • It's the first non-zero digit (pre == -1)
  • It differs from the previous digit by exactly 1 (abs(i - pre) == 1)

The new state has lead = False since we've placed a non-leading digit, and limit remains true only if we placed the maximum allowed digit.

Computing the Final Answer

To find stepping numbers in [low, high]:

  1. Calculate stepping numbers from 1 to high:
num = high
a = dfs(0, -1, True, True)
  1. Calculate stepping numbers from 1 to low - 1:
num = str(int(low) - 1)
b = dfs(0, -1, True, True)
  1. Return the difference:
return (a - b) % mod

Optimization with Memoization

The @cache decorator automatically memoizes the results of dfs calls. This ensures each unique state is computed only once, dramatically reducing the time complexity. The cache is cleared between computing a and b using dfs.cache_clear() since they work with different target numbers.

Time and Space Complexity

  • Time Complexity: O(log M × |Σ|²) where M is the value of high and |Σ| = 10 (digit set size)
  • Space Complexity: O(log M × |Σ|) for the memoization cache

The digit DP approach elegantly handles the massive range by only exploring valid digit combinations, making it feasible to solve problems with numbers having hundreds of digits.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through finding stepping numbers in the range [10, 15].

Step 1: Calculate stepping numbers from 1 to 15

We'll trace through building stepping numbers up to 15 using dfs(pos, pre, lead, limit):

Starting with num = "15", dfs(0, -1, True, True):

  • Position 0, we can place digits 0 or 1 (limited by '1' in "15")
    • If we place 0: Continue with leading zeros, dfs(1, -1, True, False)
    • If we place 1: First real digit, dfs(1, 1, False, True)

Following the path where we placed 1:

  • Position 1, previous digit is 1, limit is True (bound by '5')
    • Valid next digits must satisfy |digit - 1| = 1, so only 0 or 2
    • We can place 0: |0-1| = 1 ✓, gives us "10"
    • We can place 2: |2-1| = 1 ✓, gives us "12"
    • We cannot place 3,4,5: |3-1| = 2, |4-1| = 3, |5-1| = 4

The complete stepping numbers from 1 to 15 are:

  • Single digits: 1, 2, 3, 4, 5, 6, 7, 8, 9 (9 numbers)
  • Two digits: 10, 12 (2 numbers)
  • Total: 11 stepping numbers

Step 2: Calculate stepping numbers from 1 to 9 (low - 1)

With num = "9", dfs(0, -1, True, True):

  • Position 0, we can place digits 0 to 9
    • Placing 1-9 gives us the single-digit stepping numbers: 1,2,3,4,5,6,7,8,9
  • Total: 9 stepping numbers

Step 3: Find the answer

Stepping numbers in [10, 15] = Stepping numbers in [1, 15] - Stepping numbers in [1, 9] = 11 - 9 = 2

The stepping numbers are: 10 and 12

Let's verify:

  • 10: |1-0| = 1
  • 11: |1-1| = 0 ✗ (not a stepping number)
  • 12: |1-2| = 1
  • 13: |1-3| = 2
  • 14: |1-4| = 3
  • 15: |1-5| = 4

The digit DP approach efficiently found both valid stepping numbers without checking every number in the range!

Solution Implementation

1class Solution:
2    def countSteppingNumbers(self, low: str, high: str) -> int:
3        """
4        Count stepping numbers in range [low, high].
5        A stepping number is a number where each digit differs from its adjacent digit by exactly 1.
6        Uses digit DP technique to count numbers within bounds.
7        """
8        from functools import cache
9      
10        MOD = 10**9 + 7
11      
12        @cache
13        def count_stepping_numbers_up_to(number_str: str) -> int:
14            """
15            Count stepping numbers from 0 to number_str using digit DP.
16            """
17            @cache
18            def dp(position: int, previous_digit: int, is_leading_zero: bool, is_bounded: bool) -> int:
19                """
20                Dynamic programming function to count stepping numbers.
21              
22                Args:
23                    position: Current position in the number being formed
24                    previous_digit: Previous digit placed (-1 if no digit placed yet)
25                    is_leading_zero: True if we're still in leading zeros
26                    is_bounded: True if we must respect the upper bound at current position
27              
28                Returns:
29                    Count of valid stepping numbers from this state
30                """
31                # Base case: reached end of number
32                if position >= len(number_str):
33                    # Return 1 if we've placed at least one non-zero digit
34                    return int(not is_leading_zero)
35              
36                # Determine the maximum digit we can place at current position
37                max_digit = int(number_str[position]) if is_bounded else 9
38              
39                count = 0
40              
41                # Try placing each possible digit at current position
42                for digit in range(max_digit + 1):
43                    # Case 1: Continue with leading zeros
44                    if digit == 0 and is_leading_zero:
45                        count += dp(
46                            position + 1,
47                            previous_digit,
48                            True,  # Still have leading zeros
49                            is_bounded and (digit == max_digit)
50                        )
51                    # Case 2: Place a valid digit (first digit or stepping constraint satisfied)
52                    elif previous_digit == -1 or abs(digit - previous_digit) == 1:
53                        count += dp(
54                            position + 1,
55                            digit,
56                            False,  # No longer have leading zeros
57                            is_bounded and (digit == max_digit)
58                        )
59              
60                return count % MOD
61          
62            return dp(0, -1, True, True)
63      
64        # Count stepping numbers up to high
65        count_up_to_high = count_stepping_numbers_up_to(high)
66      
67        # Clear cache before computing for low-1
68        count_stepping_numbers_up_to.cache_clear()
69      
70        # Count stepping numbers up to (low - 1)
71        low_minus_one = str(int(low) - 1)
72        count_up_to_low_minus_one = count_stepping_numbers_up_to(low_minus_one)
73      
74        # Return the difference to get count in range [low, high]
75        return (count_up_to_high - count_up_to_low_minus_one) % MOD
76
1import java.math.BigInteger;
2
3class Solution {
4    // Modulo value for the result
5    private final int MOD = (int) 1e9 + 7;
6  
7    // Current number being processed as a string
8    private String currentNumber;
9  
10    // Memoization table: dp[position][previousDigit]
11    // Stores the count of valid stepping numbers from position with given previous digit
12    private Integer[][] dp;
13
14    /**
15     * Counts stepping numbers in the range [low, high]
16     * A stepping number is a number where all adjacent digits have an absolute difference of 1
17     * @param low The lower bound of the range (inclusive)
18     * @param high The upper bound of the range (inclusive)
19     * @return The count of stepping numbers in the range modulo 10^9 + 7
20     */
21    public int countSteppingNumbers(String low, String high) {
22        // Calculate stepping numbers from 0 to high
23        dp = new Integer[high.length() + 1][10];
24        currentNumber = high;
25        int countUpToHigh = digitDP(0, -1, true, true);
26      
27        // Calculate stepping numbers from 0 to (low - 1)
28        dp = new Integer[high.length() + 1][10];
29        currentNumber = new BigInteger(low).subtract(BigInteger.ONE).toString();
30        int countUpToLowMinus1 = digitDP(0, -1, true, true);
31      
32        // Return the difference: count[low, high] = count[0, high] - count[0, low-1]
33        return (countUpToHigh - countUpToLowMinus1 + MOD) % MOD;
34    }
35
36    /**
37     * Digit DP recursive function to count stepping numbers
38     * @param position Current position in the number (0-indexed from left)
39     * @param previousDigit The digit placed at the previous position (-1 if no previous digit)
40     * @param hasLeadingZeros True if we haven't placed any non-zero digit yet
41     * @param isTight True if we're still bounded by the original number's digits
42     * @return Count of valid stepping numbers from this state
43     */
44    private int digitDP(int position, int previousDigit, boolean hasLeadingZeros, boolean isTight) {
45        // Base case: reached the end of the number
46        if (position >= currentNumber.length()) {
47            // If we still have leading zeros, the number is 0 (don't count it)
48            // Otherwise, we've formed a valid stepping number
49            return hasLeadingZeros ? 0 : 1;
50        }
51      
52        // Check memoization for non-tight, non-leading-zero states
53        if (!hasLeadingZeros && !isTight && dp[position][previousDigit] != null) {
54            return dp[position][previousDigit];
55        }
56      
57        int result = 0;
58      
59        // Determine the upper limit for the current digit
60        int upperLimit = isTight ? currentNumber.charAt(position) - '0' : 9;
61      
62        // Try all possible digits at the current position
63        for (int digit = 0; digit <= upperLimit; ++digit) {
64            // Case 1: Continue with leading zeros
65            if (digit == 0 && hasLeadingZeros) {
66                result += digitDP(position + 1, previousDigit, true, isTight && digit == upperLimit);
67            }
68            // Case 2: Valid stepping number digit
69            // Either it's the first non-zero digit or it differs by 1 from the previous digit
70            else if (previousDigit == -1 || Math.abs(previousDigit - digit) == 1) {
71                result += digitDP(position + 1, digit, false, isTight && digit == upperLimit);
72            }
73          
74            result %= MOD;
75        }
76      
77        // Memoize the result for non-tight, non-leading-zero states
78        if (!hasLeadingZeros && !isTight) {
79            dp[position][previousDigit] = result;
80        }
81      
82        return result;
83    }
84}
85
1class Solution {
2public:
3    int countSteppingNumbers(string low, string high) {
4        const int MOD = 1e9 + 7;
5        int maxLength = high.size();
6      
7        // dp[position][lastDigit] = count of valid numbers
8        // -1 indicates not computed yet
9        int dp[maxLength + 1][10];
10        memset(dp, -1, sizeof(dp));
11      
12        string currentNumber = high;
13      
14        // Digit DP function to count stepping numbers
15        // pos: current position in the number being formed
16        // previousDigit: the previous digit placed (-1 if no digit placed yet)
17        // isLeadingZero: true if we're still in leading zeros
18        // isTight: true if we're still bounded by the upper limit
19        function<int(int, int, bool, bool)> digitDP = [&](int pos, int previousDigit, bool isLeadingZero, bool isTight) {
20            // Base case: reached end of number
21            if (pos >= currentNumber.size()) {
22                // Don't count if entire number is just leading zeros
23                return isLeadingZero ? 0 : 1;
24            }
25          
26            // Memoization: return cached result if available
27            // Only cache when not in special states (no leading zeros, not tight)
28            if (!isLeadingZero && !isTight && dp[pos][previousDigit] != -1) {
29                return dp[pos][previousDigit];
30            }
31          
32            // Determine upper bound for current digit
33            int upperBound = isTight ? (currentNumber[pos] - '0') : 9;
34            int result = 0;
35          
36            // Try all possible digits at current position
37            for (int digit = 0; digit <= upperBound; ++digit) {
38                // Handle leading zeros case
39                if (digit == 0 && isLeadingZero) {
40                    // Continue with leading zeros
41                    result += digitDP(pos + 1, previousDigit, true, isTight && (digit == upperBound));
42                } 
43                // Check stepping number constraint
44                else if (previousDigit == -1 || abs(previousDigit - digit) == 1) {
45                    // Valid stepping number digit or first non-zero digit
46                    result += digitDP(pos + 1, digit, false, isTight && (digit == upperBound));
47                }
48                result %= MOD;
49            }
50          
51            // Cache the result for non-special states
52            if (!isLeadingZero && !isTight) {
53                dp[pos][previousDigit] = result;
54            }
55          
56            return result;
57        };
58      
59        // Count stepping numbers from 0 to high
60        int countUpToHigh = digitDP(0, -1, true, true);
61      
62        // Reset memoization table for second calculation
63        memset(dp, -1, sizeof(dp));
64      
65        // Decrement low by 1 to get (low - 1)
66        // This allows us to use countUpToHigh - countUpToLowMinus1
67        for (int i = low.size() - 1; i >= 0; --i) {
68            if (low[i] == '0') {
69                low[i] = '9';  // Borrow from next digit
70            } else {
71                low[i] -= 1;   // Decrement current digit
72                break;
73            }
74        }
75      
76        // Count stepping numbers from 0 to (low - 1)
77        currentNumber = low;
78        int countUpToLowMinus1 = digitDP(0, -1, true, true);
79      
80        // Return count of stepping numbers in range [low, high]
81        return (countUpToHigh - countUpToLowMinus1 + MOD) % MOD;
82    }
83};
84
1/**
2 * Counts the number of stepping numbers between low and high (inclusive).
3 * A stepping number is a positive integer where each adjacent digit differs by exactly 1.
4 * @param low - The lower bound as a string
5 * @param high - The upper bound as a string
6 * @returns The count of stepping numbers modulo 10^9 + 7
7 */
8function countSteppingNumbers(low: string, high: string): number {
9    const MOD = 1e9 + 7;
10    const maxLength = high.length;
11  
12    // Memoization table: dp[position][previousDigit]
13    // Stores the count of valid numbers from current position with given previous digit
14    let memoTable: number[][] = Array(maxLength + 1)
15        .fill(0)
16        .map(() => Array(10).fill(-1));
17  
18    let currentNumber = high;
19  
20    /**
21     * Dynamic programming function using digit DP technique
22     * @param position - Current position in the number being formed
23     * @param previousDigit - The previous digit selected (-1 if no digit selected yet)
24     * @param hasLeadingZeros - Whether we still have leading zeros
25     * @param isTight - Whether we're still bounded by the limit number
26     * @returns Count of valid stepping numbers from current state
27     */
28    const digitDP = (
29        position: number, 
30        previousDigit: number, 
31        hasLeadingZeros: boolean, 
32        isTight: boolean
33    ): number => {
34        // Base case: reached end of number
35        if (position >= currentNumber.length) {
36            // Return 1 if we formed a valid number (not just leading zeros)
37            return hasLeadingZeros ? 0 : 1;
38        }
39      
40        // Check memoization for non-tight, non-leading-zero states
41        if (!hasLeadingZeros && !isTight && memoTable[position][previousDigit] !== -1) {
42            return memoTable[position][previousDigit];
43        }
44      
45        let count = 0;
46        // Determine upper bound for current digit
47        const upperBound = isTight ? Number(currentNumber[position]) : 9;
48      
49        // Try all possible digits at current position
50        for (let digit = 0; digit <= upperBound; digit++) {
51            if (digit === 0 && hasLeadingZeros) {
52                // Continue with leading zeros
53                count += digitDP(
54                    position + 1, 
55                    previousDigit, 
56                    true, 
57                    isTight && digit === upperBound
58                );
59            } else if (previousDigit === -1 || Math.abs(previousDigit - digit) === 1) {
60                // First non-zero digit or valid stepping number transition
61                count += digitDP(
62                    position + 1, 
63                    digit, 
64                    false, 
65                    isTight && digit === upperBound
66                );
67            }
68            count %= MOD;
69        }
70      
71        // Memoize result for non-tight, non-leading-zero states
72        if (!hasLeadingZeros && !isTight) {
73            memoTable[position][previousDigit] = count;
74        }
75      
76        return count;
77    };
78  
79    // Count stepping numbers from 0 to high
80    const countUpToHigh = digitDP(0, -1, true, true);
81  
82    // Calculate (low - 1) for exclusive lower bound
83    currentNumber = (BigInt(low) - 1n).toString();
84  
85    // Reset memoization table for new calculation
86    memoTable = Array(maxLength + 1)
87        .fill(0)
88        .map(() => Array(10).fill(-1));
89  
90    // Count stepping numbers from 0 to (low - 1)
91    const countUpToLowMinus1 = digitDP(0, -1, true, true);
92  
93    // Return the difference (with proper modulo handling)
94    return (countUpToHigh - countUpToLowMinus1 + MOD) % MOD;
95}
96

Time and Space Complexity

Time Complexity: O(n * 10 * 2 * 2) = O(n) where n is the number of digits in the input number.

The analysis breaks down as follows:

  • The DFS function explores states defined by four parameters: (pos, pre, lead, limit)
  • pos ranges from 0 to n-1 (length of the number string)
  • pre can take values from -1 to 9 (11 possible values)
  • lead is a boolean (2 possible values)
  • limit is a boolean (2 possible values)
  • Total possible states: n * 11 * 2 * 2 = 44n
  • Each state is computed once due to memoization with @cache
  • Within each state, we iterate through at most 10 digits (0-9)
  • Therefore, total operations: O(n * 11 * 2 * 2 * 10) = O(440n) = O(n)

Since the function is called twice (once for high and once for low-1), the overall time complexity remains O(n).

Space Complexity: O(n * 11 * 2 * 2) = O(n)

The space is consumed by:

  • The memoization cache stores all possible states: n * 11 * 2 * 2 = 44n states
  • The recursion stack depth is at most n (the length of the number)
  • Therefore, the total space complexity is O(44n + n) = O(n)

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Incorrect Handling of the Lower Bound Subtraction

The Pitfall: When calculating stepping numbers in range [low, high], developers often make the mistake of directly converting low to an integer for subtraction without considering edge cases:

# WRONG: This fails when low = "10"
low_minus_one = str(int(low) - 1)  # Results in "9"

The problem occurs when low - 1 results in a number with fewer digits. For example, if low = "10", then low - 1 = 9. This can cause issues if the digit DP implementation doesn't properly handle numbers with different lengths, or when low = "1" (resulting in "0"), which needs special treatment.

Solution: Handle the edge case where low equals "1" separately:

if low == "1":
    # All stepping numbers from 1 to high
    return count_stepping_numbers_up_to(high)
else:
    low_minus_one = str(int(low) - 1)
    return (count_stepping_numbers_up_to(high) - 
            count_stepping_numbers_up_to(low_minus_one)) % MOD

2. Cache Pollution Between Different Number Calculations

The Pitfall: Using the same memoization cache for different target numbers (high and low-1) without clearing it:

# WRONG: Using same cache for different numbers
@cache
def dfs(pos, pre, lead, limit):
    # ... implementation ...

# Computing for 'high'
num = high
a = dfs(0, -1, True, True)

# Computing for 'low-1' with polluted cache
num = str(int(low) - 1)
b = dfs(0, -1, True, True)  # Wrong results!

The cache contains results specific to the first number, which will give incorrect results for the second number since the limit parameter depends on the actual digits of the target number.

Solution: Either clear the cache between calculations or use separate functions:

# Option 1: Clear cache
dfs.cache_clear()

# Option 2: Use number as parameter
@cache
def dfs(num_str, pos, pre, lead, limit):
    up = int(num_str[pos]) if limit else 9
    # ... rest of implementation

3. Forgetting the Modulo Operation

The Pitfall: Not applying modulo at intermediate steps, potentially causing integer overflow in languages with fixed integer sizes, or forgetting the final modulo:

# WRONG: Only applying modulo at the end
count = 0
for digit in range(max_digit + 1):
    count += dp(...)  # Can overflow
return count % MOD

# WRONG: Negative results from subtraction
return (a - b) % MOD  # If b > a, this gives wrong answer in some languages

Solution: Apply modulo consistently and handle potential negative results:

# Correct approach
count = 0
for digit in range(max_digit + 1):
    count = (count + dp(...)) % MOD

# For subtraction, ensure positive result
return (a - b + MOD) % MOD

4. Misunderstanding the Leading Zero Logic

The Pitfall: Incorrectly treating leading zeros as part of the stepping number validation:

# WRONG: Checking stepping constraint for leading zeros
if digit == 0 and is_leading_zero:
    if previous_digit == -1 or abs(digit - previous_digit) == 1:
        count += dp(...)  # Wrong! Leading zeros shouldn't be validated

Leading zeros are not part of the actual number and shouldn't participate in the stepping number constraint check. The number "0123" is actually just "123".

Solution: Handle leading zeros separately without checking the stepping constraint:

if digit == 0 and is_leading_zero:
    # Continue with leading zeros, no stepping check needed
    count += dp(position + 1, previous_digit, True, ...)
elif previous_digit == -1 or abs(digit - previous_digit) == 1:
    # Only check stepping constraint for actual digits
    count += dp(position + 1, digit, False, ...)
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

What's the output of running the following function using the following tree as input?

1def serialize(root):
2    res = []
3    def dfs(root):
4        if not root:
5            res.append('x')
6            return
7        res.append(root.val)
8        dfs(root.left)
9        dfs(root.right)
10    dfs(root)
11    return ' '.join(res)
12
1import java.util.StringJoiner;
2
3public static String serialize(Node root) {
4    StringJoiner res = new StringJoiner(" ");
5    serializeDFS(root, res);
6    return res.toString();
7}
8
9private static void serializeDFS(Node root, StringJoiner result) {
10    if (root == null) {
11        result.add("x");
12        return;
13    }
14    result.add(Integer.toString(root.val));
15    serializeDFS(root.left, result);
16    serializeDFS(root.right, result);
17}
18
1function serialize(root) {
2    let res = [];
3    serialize_dfs(root, res);
4    return res.join(" ");
5}
6
7function serialize_dfs(root, res) {
8    if (!root) {
9        res.push("x");
10        return;
11    }
12    res.push(root.val);
13    serialize_dfs(root.left, res);
14    serialize_dfs(root.right, res);
15}
16

Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More