困难 - 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)
};
相关推荐
计算机安禾19 分钟前
【数据结构与算法】第35篇:归并排序与基数排序
c语言·数据结构·vscode·算法·排序算法·哈希算法·visual studio
爱码小白30 分钟前
MySQL 单表查询练习题汇总
数据库·python·算法
橘颂TA32 分钟前
【笔试】算法的暴力美学——牛客 NC213140 :除2!
c++·算法·结构与算法
汀、人工智能1 小时前
[特殊字符] 第66课:跳跃游戏
数据结构·算法·数据库架构·图论·bfs·跳跃游戏
汀、人工智能1 小时前
[特殊字符] 第70课:加油站
数据结构·算法·数据库架构·图论·bfs·加油站
wsoz1 小时前
Leetcode普通数组-day5、6
c++·算法·leetcode·数组
y = xⁿ1 小时前
【LeetCode】双指针:同向快慢针
算法·leetcode
啊哦呃咦唔鱼1 小时前
LeetCode hot100-105从前序与中序遍历序列构造二叉树
算法
favour_you___1 小时前
2026_4_8算法练习题
数据结构·c++·算法
汀、人工智能1 小时前
[特殊字符] 第57课:搜索旋转排序数组
数据结构·算法·数据库架构·图论·bfs·搜索旋转排序数组