困难 - 2999. 统计强大整数的数目

Problem: 2999. 统计强大整数的数目

思路

递归 动态规划-记忆化搜索

解题过程

  • 假设合法数字s,首先每一位数i上能选择的数字有三个限制 >=start[i] <=finish[i]<=limit
  • 但是有些情况下-这三个条件里可以只满足<=limit
    • 例如 在【19,30】 limit=5里 25 是一个合法数字,而此时 5 明显 不符合上面三个条件中其他两个
  • 我们得出规律,当s[i-1]<finish[i-1]时 s[i]的取值范围是【0,9】,当s[i-1]=finish[i-1]时 s[i]的取值范围是【0,min(finish[i],limit)】,同理当s[i-1]>start[i-1]时 s[i]的取值范围是【0,limit】,当s[i-1]=start[i-1]时 s[i]的取值范围是`【start[i],min(finish[i],limit)】
  • 所以每一次i的取值范围都是i-1取了什么值来确定的
  • 设置dfs(i, low, top) i为当前位数,low为是否限制取最小值 top为是否限制取最大值, 即值为true的话,表示i-1选取了一个边界值
  • 递归入口是 dfs(0, true, true) 出口是 dfs(n, xxx, xxx) nfinish的长度
  • 优化:由于有限制的原因 所以取到边界值时结果是不确定的,只有lowtop 都为 false 时,取值的范围是【0,9】,此时记录下位数i里的合法情况有多少,再次进入循环i时可以直接使用记录的数量

复杂度

  • 时间复杂度: O()
  • 空间复杂度: O(n)

Code

Javascript 复制代码
var numberOfPowerfulInt = function (start, finish, limit, s) {
    if (Number(s) > finish) {
        return 0
    }

    // dfs() 暴力递归  然后记忆之前搜索时 每一步的数量
    // 由于 low 和 top 会有限制 所以不能用于所有情况 只记录 都为false 的情况下 有多少结果
    // dfs(i, low, top ) i 代表第几位 low 是否要求最低限制 不限制从0开始 top 同理 还有个limit
    const n = `${finish}`.length;
    const sn = n - s.length;
    const has = new Array(n).fill(-1);

    let lowarr = `${start}`.padStart(n, "0");
    let toparr = `${finish}`.padStart(n, "0");

    function dfs(i, low, top) {
        if (i == n) {
            return 1
        }
        
        //当下一次循环进入到 i 时
        if (!low && !top && has[i] != -1) {
            return has[i];
        }
        
        // 计算出能取值范围
        let li = low ? lowarr[i] : 0;
        let ti = top ? Math.min(toparr[i], limit) : limit;
        let result = 0;

        if (i < sn) {
            
            for (let j = li; j <= ti; j++) {
                // dfs(i + 1, j == lowarr[i] ? low : false, j == toparr[i] ? top : false)
                result += dfs(i + 1, j == li && low, j == toparr[i] && top)
            }

        } else {
            // 此时 已经是后缀的范围了 必须使用后缀
            const si = s[i - sn];
            
            if (si >= li && si <= ti) {
                // dfs(i+1, si == li ? low : false, si == ti ? top : false)
                result = dfs(i + 1, si == li && low, si == ti && top)
            }
        }

        if (!low && !top) {
            has[i] = result;
        }

        return result
    }

    return dfs(0, true, true)
};
相关推荐
知其然亦知其所以然18 小时前
国产大模型也能无缝接入!Spring AI + 智谱 AI 实战指南
java·后端·算法
然我20 小时前
搞定异步任务依赖:Promise.all 与拓扑排序的妙用
前端·javascript·算法
徐小夕21 小时前
支持1000+用户同时在线的AI多人协同文档JitWord,深度剖析
前端·vue.js·算法
沐怡旸2 天前
【算法】【链表】328.奇偶链表--通俗讲解
算法·面试
掘金安东尼2 天前
Amazon Lambda + API Gateway 实战,无服务器架构入门
算法·架构
码流之上2 天前
【一看就会一写就废 指间算法】设计电子表格 —— 哈希表、字符串处理
javascript·算法
快手技术2 天前
快手提出端到端生成式搜索框架 OneSearch,让搜索“一步到位”!
算法
CoovallyAIHub3 天前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP3 天前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo3 天前
半开区间和开区间的两个二分模版
算法