LC 6957. 统计范围内的步进数字数目
https://leetcode.cn/problems/count-stepping-numbers-in-range/
6月份有道数位dp的题目,当时看了有点似懂非懂的,今天正好试试,看看自己能不能做出来。
其中 `F(s)` 是计算小于等于s的,并且满足条件的数的个数。
- i 表示寻找第几位
- last 表示上一位选择的数字,可以是0. 但是需要判断这个0是不是第一个,由 `isFirst` 来判断
- isLimit 表示之前选择的数字,已经确保可以小于s了。如果已经确保的话,那么在选择上空间不同。
- isFirst 表示目前选择是不是第一个数字。
def F(s): @functools.cache def search(i, last, isLimit, isFirst): if i == len(s): return 0 if isFirst else 1 ans = 0 h = int(s[i]) if isFirst: h2 = 9 if isLimit else h for d in range(0, h2 + 1): ans += search(i + 1, d, isLimit or d < h, d == 0) else: for d in (last - 1, last + 1): if d < 0 or d > 9 or (not isLimit and d > h): continue ans += search(i + 1, d, isLimit or d < h, False) return ans return search(0, 0, False, True) def check(s): for i in range(1, len(s)): d = ord(s[i]) - ord(s[i - 1]) if not (d == 1 or d == -1): return False return True class Solution: def countSteppingNumbers(self, low: str, high: str) -> int: MOD = 10 ** 9 + 7 h = F(high) l = F(low) ans = h - l if check(low): ans += 1 return ans % MOD