LC 6957. 统计范围内的步进数字数目

https://leetcode.cn/problems/count-stepping-numbers-in-range/

6月份有道数位dp的题目,当时看了有点似懂非懂的,今天正好试试,看看自己能不能做出来。

其中 `F(s)` 是计算小于等于s的,并且满足条件的数的个数。

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