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

Posted ambition-hhn

tags:

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

给定正整数N,返回小于等于N且至少具有1位重复数字的正整数。当时没想到思路,只想到有重复数位的数不好算,但是不含有重复数字的数的个数可以算,后来看了一个人的解答,用数位dp+排列可以做出来。大致分为两部分,设这个数字有k位,第一部分计算是数字不到k位的数且这些数每一位的数字不相同,第二部分是计算k位数的满足上述条件的个数,具体可见代码。下图是一个计算的例子。
技术图片

class Solution {
public:
    int vis[10];
    int ans=0;
    int k=0;
    int A(int i,int j)
    {
        int now=1,tmp=i;
        for(int k=0;k<j;k++)
        {
            now*=tmp;
            tmp--;
        }
        return now;
    }

    void dfs1(int now)
    {
        if(now<k-1)
        {
            ans+=9*A(9,now);
            dfs1(now+1);
        }
    } 

    void dfs2(int now,vector<int>& v)
    {
        if(now==0)
        {
            int pos=k-now-1;
            vis[v[pos]]=1;
            ans+=(v[pos]-1)*A(9-now,k-1-now);
            dfs2(now+1,v);
        }
        else if(now<k)
        {
            int pos=k-now-1;
            int cnt=0;
            for(int i=0;i<v[pos];i++) 
            if(vis[i])
            cnt++;
            ans+=(v[pos]-cnt)*A(9-now,k-1-now);
            if(vis[v[pos]]==1) return ;
            vis[v[pos]]=1;
            dfs2(now+1,v);
        }

        if(now==k)
        {
            ans+=1;
        }
    }

    int numDupDigitsAtMostN(int N) {
    int tmp=N;
    vector<int> v;
    while(tmp)
    {
        v.push_back(tmp%10);
        tmp/=10;
    }
    k=v.size();
    dfs1(0);
    dfs2(0,v);
    ans=N-ans;
    return ans;
    }
};

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

LeetCode至 少有 1 位重复的数字

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

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

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

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

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