码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2020-05-01 18:48:28      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:atm   return   else   void   ==   ++   大致   git   重复   

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

标签:atm   return   else   void   ==   ++   大致   git   重复   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!