困难 - 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)
};
相关推荐
团子的二进制世界14 分钟前
G1垃圾收集器是如何工作的?
java·jvm·算法
吃杠碰小鸡18 分钟前
高中数学-数列-导数证明
前端·数学·算法
故事不长丨18 分钟前
C#线程同步:lock、Monitor、Mutex原理+用法+实战全解析
开发语言·算法·c#
long31618 分钟前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
近津薪荼19 分钟前
dfs专题4——二叉树的深搜(验证二叉搜索树)
c++·学习·算法·深度优先
熊文豪28 分钟前
探索CANN ops-nn:高性能哈希算子技术解读
算法·哈希算法·cann
熊猫_豆豆1 小时前
YOLOP车道检测
人工智能·python·算法
艾莉丝努力练剑1 小时前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
偷吃的耗子2 小时前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
dazzle2 小时前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习