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

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

思路

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

解题过程

  • 假设合法数字s,首先每一位数i上能选择的数字有三个限制 >=start[i] <=finish[i]<=limit
  • 但是有些情况下-这三个条件里可以只满足<=limit
    • 例如 在【19,30】 limit=5里 25 是一个合法数字,而此时 5 明显 不符合上面三个条件中其他两个
  • 我们得出规律,当s[i-1]<finish[i-1]时 si的取值范围是【0,9】,当s[i-1]=finish[i-1]时 si的取值范围是【0,min(finishi,limit)】,同理当s[i-1]>start[i-1]时 si的取值范围是【0,limit】,当s[i-1]=start[i-1]时 si的取值范围是`【starti,min(finishi,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)
};
相关推荐
sali-tec5 分钟前
C# 基于OpenCv的视觉工作流-章108-区域筛选
图像处理·人工智能·opencv·算法·计算机视觉
Gigavision6 小时前
基于BUAA-MIHR数据集的噪声解耦对比学习算法
人工智能·python·深度学习·算法
鹿角片ljp6 小时前
LeetCode 64:最小路径和复盘|二维 DP 与 ACM 模式完整写法
java·数据结构·算法
彧azz7 小时前
算法设计与分析:贪心与动态规划
数据结构·学习·算法·贪心算法·动态规划
Beyond_System|系统之外8 小时前
【学编程】Python基础编程题100道(21-60)
开发语言·python·算法
漂流瓶jz10 小时前
UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版
c++·算法·题解·aoapc·算法竞赛入门经典·uva
叠层归一研究院11 小时前
基于极限自指的叠层归一宇宙结构理论——无元外部封闭系统的内生区分模型
人工智能·经验分享·算法·agi
Selvaggia12 小时前
Diffusion Model 的基本原理与模型架构
算法
wabs66613 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
hanlin0313 小时前
刷题笔记:力扣第41题-缺失的第一个正数
笔记·算法·leetcode