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;
        }
    };
    
  • 相关阅读:
    shell 表达式
    manjaro 换源到中国并按照速度排序
    ORA-01950:对表空间 'USERS' 无权限
    normal 普通身份 sysdba 系统管理员身份 sysoper 系统操作员身份 dba和sysdba
    学生选课数据库SQL语句练习题
    多线程编程
    补充知识点
    输入输出
    集合作业
    银行(1)0925
  • 原文地址:https://www.cnblogs.com/ambition-hhn/p/12814146.html
Copyright © 2011-2022 走看看