LeetCode至 少有 1 位重复的数字

Posted blueattack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode至 少有 1 位重复的数字相关的知识,希望对你有一定的参考价值。

 

给定正整数 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

数位dp可以解决,不知道怎么写。
考虑一种通解的方法:原答案即N-没有重复的数字。关键是求没有重复的数字
对于位数比N小的情况,我们可以直接排列组合求。
对于与N相同的情况,我们从最高位根据数字的限制(limit)依此排列求解
int C(int m,int n)
    {
        int res=1;
        while(n)
        {
            res*=m;
            m--;
            n--;
        }           
        return res;
    }
    int numDupDigitsAtMostN(int N) {
        vector<int>a;
        
        for(int x=N+1;x!=0;x/=10)
            a.push_back(x%10);
        int n=a.size();
        reverse(a.begin(),a.end());
        int res=0;
        for(int i=1;i<n;i++)
            res+=9*C(9,i-1);
        cout<<res<<endl;
        map<int,int>contain;
        for(int i=0;i<n;i++)
        {
            for(int j=i>0?0:1;j<a[i];j++)
            {
                if(contain[j]==0)
                    res+=C(9-i,n-i-1);
            }
            if(contain[a[i]]>0)
                break;
            contain[a[i]]++;
            
        }
        return N-res;
    }

数位dp

int dfs(int t, bool up, bool ze, bool rp, int mask) {
        if (t < 0) return rp;
        if (!up && ~dp[t][ze][rp][mask]) return dp[t][ze][rp][mask];
        int ret = 0, I = up ? a[t] : 9;
        rep(i, 0, I + 1) {
            bool nrp = rp;
            int nmas = mask;
            if (!(ze & i == 0)) {
                nrp |= mask >> i & 1;
                nmas |= 1 << i;
            }
            ret += dfs(t - 1, up & (i == I), ze & (i == 0),
                nrp, nmas);
        }
        if (!up) dp[t][ze][rp][mask] = ret;
        return ret;
    }

    int numDupDigitsAtMostN(int N) {
        memset(dp, -1, sizeof(dp));
        int n = 0;
        while (N > 0) {
            a[n++] = N % 10;
            N /= 10;
        }
        return dfs(n - 1, 1, 1, 0, 0);        
    }

 




以上是关于LeetCode至 少有 1 位重复的数字的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode-1015 Numbers With Repeated Digits(至少有 1 位重复的数字)

1012. 至少有 1 位重复的数字

LeetCode395-至少有 K 个重复字符的最长子串

leetcode 395 至少有K个重复字符的最长子串

LeetCode 0395. 至少有 K 个重复字符的最长子串

LeetCode-递归至少有K个重复字符的最长子串