Welcome to Subscribe On Youtube

2801. Count Stepping Numbers in Range

Description

Given two positive integers low and high represented as strings, find the count of stepping numbers in the inclusive range [low, high].

A stepping number is an integer such that all of its adjacent digits have an absolute difference of exactly 1.

Return an integer denoting the count of stepping numbers in the inclusive range [low, high].

Since the answer may be very large, return it modulo 109 + 7.

Note: A stepping number should not have a leading zero.

 

Example 1:

Input: low = "1", high = "11"
Output: 10
Explanation: The stepping numbers in the range [1,11] are 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10. There are a total of 10 stepping numbers in the range. Hence, the output is 10.

Example 2:

Input: low = "90", high = "101"
Output: 2
Explanation: The stepping numbers in the range [90,101] are 98 and 101. There are a total of 2 stepping numbers in the range. Hence, the output is 2. 

 

Constraints:

  • 1 <= int(low) <= int(high) < 10100
  • 1 <= low.length, high.length <= 100
  • low and high consist of only digits.
  • low and high don't have any leading zeros.

Solutions

  • import java.math.BigInteger;
    
    class Solution {
        private final int mod = (int) 1e9 + 7;
        private String num;
        private Integer[][] f;
    
        public int countSteppingNumbers(String low, String high) {
            f = new Integer[high.length() + 1][10];
            num = high;
            int a = dfs(0, -1, true, true);
            f = new Integer[high.length() + 1][10];
            num = new BigInteger(low).subtract(BigInteger.ONE).toString();
            int b = dfs(0, -1, true, true);
            return (a - b + mod) % mod;
        }
    
        private int dfs(int pos, int pre, boolean lead, boolean limit) {
            if (pos >= num.length()) {
                return lead ? 0 : 1;
            }
            if (!lead && !limit && f[pos][pre] != null) {
                return f[pos][pre];
            }
            int ans = 0;
            int up = limit ? num.charAt(pos) - '0' : 9;
            for (int i = 0; i <= up; ++i) {
                if (i == 0 && lead) {
                    ans += dfs(pos + 1, pre, true, limit && i == up);
                } else if (pre == -1 || Math.abs(pre - i) == 1) {
                    ans += dfs(pos + 1, i, false, limit && i == up);
                }
                ans %= mod;
            }
            if (!lead && !limit) {
                f[pos][pre] = ans;
            }
            return ans;
        }
    }
    
  • class Solution {
    public:
        int countSteppingNumbers(string low, string high) {
            const int mod = 1e9 + 7;
            int m = high.size();
            int f[m + 1][10];
            memset(f, -1, sizeof(f));
            string num = high;
    
            function<int(int, int, bool, bool)> dfs = [&](int pos, int pre, bool lead, bool limit) {
                if (pos >= num.size()) {
                    return lead ? 0 : 1;
                }
                if (!lead && !limit && f[pos][pre] != -1) {
                    return f[pos][pre];
                }
                int up = limit ? num[pos] - '0' : 9;
                int ans = 0;
                for (int i = 0; i <= up; ++i) {
                    if (i == 0 && lead) {
                        ans += dfs(pos + 1, pre, true, limit && i == up);
                    } else if (pre == -1 || abs(pre - i) == 1) {
                        ans += dfs(pos + 1, i, false, limit && i == up);
                    }
                    ans %= mod;
                }
                if (!lead && !limit) {
                    f[pos][pre] = ans;
                }
                return ans;
            };
    
            int a = dfs(0, -1, true, true);
            memset(f, -1, sizeof(f));
            for (int i = low.size() - 1; i >= 0; --i) {
                if (low[i] == '0') {
                    low[i] = '9';
                } else {
                    low[i] -= 1;
                    break;
                }
            }
            num = low;
            int b = dfs(0, -1, true, true);
            return (a - b + mod) % mod;
        }
    };
    
  • class Solution:
        def countSteppingNumbers(self, low: str, high: str) -> int:
            @cache
            def dfs(pos: int, pre: int, lead: bool, limit: bool) -> int:
                if pos >= len(num):
                    return int(not lead)
                up = int(num[pos]) if limit else 9
                ans = 0
                for i in range(up + 1):
                    if i == 0 and lead:
                        ans += dfs(pos + 1, pre, True, limit and i == up)
                    elif pre == -1 or abs(i - pre) == 1:
                        ans += dfs(pos + 1, i, False, limit and i == up)
                return ans % mod
    
            mod = 10**9 + 7
            num = high
            a = dfs(0, -1, True, True)
            dfs.cache_clear()
            num = str(int(low) - 1)
            b = dfs(0, -1, True, True)
            return (a - b) % mod
    
    
  • func countSteppingNumbers(low string, high string) int {
    	const mod = 1e9 + 7
    	f := [110][10]int{}
    	for i := range f {
    		for j := range f[i] {
    			f[i][j] = -1
    		}
    	}
    	num := high
    	var dfs func(int, int, bool, bool) int
    	dfs = func(pos, pre int, lead bool, limit bool) int {
    		if pos >= len(num) {
    			if lead {
    				return 0
    			}
    			return 1
    		}
    		if !lead && !limit && f[pos][pre] != -1 {
    			return f[pos][pre]
    		}
    		var ans int
    		up := 9
    		if limit {
    			up = int(num[pos] - '0')
    		}
    		for i := 0; i <= up; i++ {
    			if i == 0 && lead {
    				ans += dfs(pos+1, pre, true, limit && i == up)
    			} else if pre == -1 || abs(pre-i) == 1 {
    				ans += dfs(pos+1, i, false, limit && i == up)
    			}
    			ans %= mod
    		}
    		if !lead && !limit {
    			f[pos][pre] = ans
    		}
    		return ans
    	}
    	a := dfs(0, -1, true, true)
    	t := []byte(low)
    	for i := len(t) - 1; i >= 0; i-- {
    		if t[i] != '0' {
    			t[i]--
    			break
    		}
    		t[i] = '9'
    	}
    	num = string(t)
    	f = [110][10]int{}
    	for i := range f {
    		for j := range f[i] {
    			f[i][j] = -1
    		}
    	}
    	b := dfs(0, -1, true, true)
    	return (a - b + mod) % mod
    }
    
    func abs(x int) int {
    	if x < 0 {
    		return -x
    	}
    	return x
    }
    
  • function countSteppingNumbers(low: string, high: string): number {
        const mod = 1e9 + 7;
        const m = high.length;
        let f: number[][] = Array(m + 1)
            .fill(0)
            .map(() => Array(10).fill(-1));
        let num = high;
        const dfs = (pos: number, pre: number, lead: boolean, limit: boolean): number => {
            if (pos >= num.length) {
                return lead ? 0 : 1;
            }
            if (!lead && !limit && f[pos][pre] !== -1) {
                return f[pos][pre];
            }
            let ans = 0;
            const up = limit ? +num[pos] : 9;
            for (let i = 0; i <= up; i++) {
                if (i == 0 && lead) {
                    ans += dfs(pos + 1, pre, true, limit && i == up);
                } else if (pre == -1 || Math.abs(pre - i) == 1) {
                    ans += dfs(pos + 1, i, false, limit && i == up);
                }
                ans %= mod;
            }
            if (!lead && !limit) {
                f[pos][pre] = ans;
            }
            return ans;
        };
        const a = dfs(0, -1, true, true);
        num = (BigInt(low) - 1n).toString();
        f = Array(m + 1)
            .fill(0)
            .map(() => Array(10).fill(-1));
        const b = dfs(0, -1, true, true);
        return (a - b + mod) % mod;
    }
    
    

All Problems

All Solutions