美文网首页动态规划动态规划
数位DP题目:LeetCode1015. 至少有 1 位重复的数

数位DP题目:LeetCode1015. 至少有 1 位重复的数

作者: 独孤岳 | 来源:发表于2019-03-18 00:36 被阅读0次

题目链接

给定正整数 N,返回小于等于 N 且具有至少 1 位重复数字的正整数。

示例 1:

输入:20
输出:1
解释:具有至少 1 位重复数字的正数(<= 20)只有 11 。
示例 2:

输入:100
输出:10
解释:具有至少 1 位重复数字的正数(<= 100)有 11,22,33,44,55,66,77,88,99 和 100 。
示例 3:

输入:1000
输出:262
 

提示:

1 <= N <= 10^9

解答:这是一道数位DP模板题,算法见代码注释。

//author: xnjxyk
int num[10], tot;
int dp[10][1024][2];

// flag表示当前搜索结果中整数的位数是否和N一样
// lead表示当前搜索整数是否有前导0
// succ表示枚举这一位以前有没有重复
// state换算成二进制有10位,分别表示枚举到这一位之前0~9有没有被使用
// now表示当前枚举位置
int dfs(int now, int state, int succ, bool lead, bool flag){
    // 如果枚举完最后一位,那么返回succ,succ=1表示有重复的数字,succ=0表示没有重复的数字
    if (now==0) {
        printf("State = %d (%d)\n", state, succ);
        return succ;
    }
    // 记忆化,如果位数小于N,没有前导0,而且结果已经被求出来,则直接返回
    if (flag==false && lead==false && dp[now][state][succ]!=-1) return dp[now][state][succ];

    int lim=((flag==false)?9:num[now]);// 如果位数一样,则搜索上限是num[now],如果位数小于N,则搜索上限是9
    // 返回结果清零
    int ret=0;
    // 如果有前导0,那么这位只能从1开始枚举,如果没有前导0,则可以从0开始枚举
    for (int i=(lead?1:0); i<=lim; i++){
        // state|(1<<i)记录当前枚举的数字,succ|((state>>i)&1)记录当前枚举数字以后,会不会有重复
        // 这两个运算是本题数字DP的关键
        ret+=dfs(now-1, state|(1<<i), succ|((state>>i)&1), false, (flag && i==lim));
    }
    // 对应前面的记忆化
    if (flag==false && lead==false) dp[now][state][succ]=ret;
    return ret;
}

class Solution {
public:
    int numDupDigitsAtMostN(int N) {
        memset(dp, -1, sizeof(dp));
        // tot表示正整数N一共有多少位
        tot=0; while(N) num[++tot]=N%10, N/=10;
        int ans=0;
        for (int i=tot; i>=1; i--)
            ans+=dfs(i, 0, 0, true, i==tot);
        return ans;
    }
};

相关文章

  • 数位DP题目:LeetCode1015. 至少有 1 位重复的数

    题目链接 给定正整数 N,返回小于等于 N 且具有至少 1 位重复数字的正整数。 解答:这是一道数位DP模板题,算...

  • 1012. 至少有 1 位重复的数字【数位DP】

    分析:1、题目需要求数字N有多少个重复的数字,可以将其转换为求数字N有多少个不重复的数字,因为求不重复的数字可以更...

  • LeetCode1015. 至少有 1 位重复的数字

    问题描述 给定正整数 N,返回小于等于 N 且具有至少 1 位重复数字的正整数。 示例 1:输入:20输出:1解释...

  • 【进阶】数位DP详解

    今天,我向大家介绍一种特殊的DP类型——数位DP。数位DP这类题目一般不会出现在提高组及以下的比赛中(今后出现了当...

  • 动态规划-数位Dp

    记录今天在Acwing学习的几道数位Dp题目,整理了思路,方便以后的复习: 1.度的数量 题目描述 求给定区间 [...

  • 数位DP,统计1-N中含有“49”的总数

    题目:参考数位DP,统计1-N中含有“49”的总数 另一篇参考文章HDU 3555 Bomb(1-n含有“49”的...

  • Swift-整数的奇数位与偶数位

    题目:编写程序交换某个整数的奇数位和偶数位,使用指令越少越好(即位0与位1交换,位2与位3交换)。看过题目解析之后...

  • 数位dp

    数位dp是解决一类选择有约束的数字的个数的问题的解法,就是数一个区间有多少个满足题目条件的数字的个数,通常暴...

  • 数位dp

    数位dp的入门题HDU - 2089 不要62题意:求区间[n,m]之间,不含有4和(连续的)62的数字个数。分析...

  • 数位DP

    1. 计数问题 原题链接[https://www.acwing.com/problem/content/340/]...

网友评论

    本文标题:数位DP题目:LeetCode1015. 至少有 1 位重复的数

    本文链接:https://www.haomeiwen.com/subject/dqlmmqtx.html