zoukankan      html  css  js  c++  java
  • 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;
        }
    };
    
  • 相关阅读:
    寻找道路
    联合权值
    二分图
    最优贸易
    读入优化
    专属空间五——新世界(新闻浏览功能)中
    专属空间四——新世界(新闻浏览功能)上
    专属空间三——文件管理器
    专属空间二-记账本的实现
    专属空间一-主界面设计
  • 原文地址:https://www.cnblogs.com/ambition-hhn/p/12814146.html
Copyright © 2011-2022 走看看