困难 - 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)
};
相关推荐
不是吧这都有重名41 分钟前
[论文阅读]Deeply-Supervised Nets
论文阅读·人工智能·算法·大语言模型
homelook1 小时前
matlab simulink双边反激式变压器锂离子电池均衡系统,双目标均衡策略,仿真模型,提高均衡速度38%
算法
什码情况2 小时前
星际篮球争霸赛/MVP争夺战 - 华为OD机试真题(A卷、Java题解)
java·数据结构·算法·华为od·面试·机试
天上路人2 小时前
采用AI神经网络降噪算法的通信语音降噪(ENC)模组性能测试和应用
人工智能·神经网络·算法
字节高级特工2 小时前
【C++】”如虎添翼“:模板初阶
java·c语言·前端·javascript·c++·学习·算法
.Vcoistnt2 小时前
Codeforces Round 1024 (Div. 2)(A-D)
数据结构·c++·算法·贪心算法·动态规划·图论
晴天下小雨o2 小时前
排序算法总结
java·算法·排序算法
程序员爱钓鱼2 小时前
循环语句:for、range -《Go语言实战指南》
java·数据结构·算法
LabVIEW开发3 小时前
LabVIEW中算法开发的系统化解决方案与优化
算法·labview
chenyuhao20243 小时前
链表面试题7之相交链表
数据结构·算法·链表·面试·c#