首页 > 其他 > 详细

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

时间:2020-05-01 19:39:37      阅读:79      评论:0      收藏:0      [点我收藏+]

给定正整数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 位重复的数字

原文:https://www.cnblogs.com/ambition-hhn/p/12814146.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!