2999. 统计强大整数的数目
问题分析
题目描述
题目要求统计区间 [start, finish] 内的强大整数数量。强大整数需满足以下条件:
- 每位数字不超过 limit
- 以字符串 s 作为后缀
关键要点理解
- 强大整数的定义:整数的每一位都不超过 limit,且必须以字符串 s 结尾。
- 区间计数:需要统计 [start, finish] 区间内满足条件的整数个数。
- 后缀约束:数字必须以特定的字符串 s 结尾,这是一个重要的约束条件。
示例分析
分析一下示例:
示例 1:
- 输入:start = 1, finish = 6000, limit = 4, s = “124”
- 输出:5
- 解释:区间 [1…6000] 内的强大整数有 124、1124、2124、3124 和 4124。
这些数字的每个数位都 <= 4,且都以 “124” 结尾。5124 不是强大整数,因为首位数字 > 4。
示例 2:
- 输入:start = 15, finish = 215, limit = 6, s = “10”
- 输出:2
- 解释:区间 [15…215] 内的强大整数有 110 和 210。这些数字的每个数位都 <= 6,且都以 “10” 结尾。
示例 3:
- 输入:start = 1000, finish = 2000, limit = 4, s = “3000”
- 输出:0
- 解释:区间 [1000…2000] 内的数字都小于 3000,所以 “3000” 不可能是这个区间内任何数字的后缀。
解题思路
问题特性分析
这是一个典型的数位动态规划问题。需要计算满足特定条件的数字数量,其中条件涉及到数字的每一位。
这类问题的常用解法是:
- 计算 ≤ finish 的符合条件的数量
- 计算 ≤ (start-1) 的符合条件的数量
- 两者相减得到 [start, finish] 区间内的数量
基本思路
采用数位 DP 的方法,从高位到低位构建数字,同时考虑以下约束:
- 每位数字不超过 limit
- 不超过上界 (finish 或 start-1)
- 后缀必须是字符串 s
关键算法设计
设计一个递归函数 dp(pos, tight)
,其中:
pos
表示当前处理的位置(从左到右)tight
表示当前是否受到上界的限制
递归过程中,需要:
- 验证后缀 s 是否合法(每位数字都 ≤ limit)
- 分别统计位数少于目标数和位数等于目标数的情况
- 对于位数等于目标数的情况,使用数位 DP 精确计数
代码实现
class Solution:
def numberOfPowerfulInt(self, start: int, finish: int, limit: int, s: str) -> int:
# 先检查后缀 s 是否合法(每位数字都不超过 limit)