• leetcode_1015. Numbers With Repeated Digits


    https://leetcode.com/problems/numbers-with-repeated-digits/

    leetcode_357. Count Numbers with Unique Digits有一些相似的地方。

    给定N,计算小于等于N且至少有一个重复数位的数的数目。

    可转化为计算小于等于N且所有数位不相同的数的数目。且可分为两部分,

    1. 位数与N相同且小于等于N且所有数位不相同的数的数目;
    2. 位数小于N且所有数位不相同的数的数目。

    难点在于第1部分。

    解法一:

    使用dfs计算第一部分。时间上开销相对较大

    class Solution{
    public:
        int res_=0, numofdigist_=0;
        bool flag[10];
        int digists[10];
    void dfs(int numofdigist, int digist, bool smaller){ if(numofdigist == 1){ if(!smaller){ for(int i=0; i<=digist; i++) if(flag[i]==0) res_++; } else{ for(int i=0; i<=9; i++) if(flag[i]==0) res_++; } return; } for(int i=0; i<=9; i++){ if(i==0&&numofdigist==numofdigist_) continue; if(i>digist && smaller==0) break; if(flag[i]==0){ flag[i]=1; if(!smaller&&i<digist) dfs(numofdigist-1, digists[numofdigist-2], 1); else if(!smaller&&i==digist) dfs(numofdigist-1, digists[numofdigist-2], 0); else if(smaller) dfs(numofdigist-1, digists[numofdigist-2], 1); flag[i]=0; } } } int numDupDigitsAtMostN(int N){ if(N<=10) return 0; int n=N; int weight=10; while(N>0){ digists[numofdigist_++] = N%10; N/=10; } memset(flag, 0 , sizeof(flag)); dfs(numofdigist_, digists[numofdigist_-1], 0); for(int i=1;i<=numofdigist_-1;i++){ int tmp=9; for(int j=1;j<i;j++) tmp *= 9-j+1; res_+=tmp; } return n-res_; } };

    解法二:

    从最高位开始,计算当前i位相同情况下小于等于N且所有数位不相同的数的数目。

    class Solution{
    public:
        int res_=0, numofdigist_=0;
        bool flag[10];
        int digists[10];
    int calc(int num, int wei){    //计算还剩num个数没用,还剩wei位有多少种情况 int res=1; for(int i=0; i<wei; i++) res *= num-i; return res; }
    int numDupDigitsAtMostN(int N){ if(N<=10) return 0; N++;        //计算小于N的数目,更方便处理 int n=N; int weight=10; while(N>0){ //计算出N的位数和每一位的数值 digists[numofdigist_++] = N%10; N/=10; }
        //计算第1部分 memset(flag,
    0,sizeof(flag)); res_ = (digists[numofdigist_-1]-1)*calc(9,numofdigist_-1);//第1位不能为0 flag[digists[numofdigist_-1]]=1; for(int i=numofdigist_-2; i>=0; i--){ for(int j=0; j<digists[i]; j++) if(flag[j]==0) res_ += calc(9-numofdigist_+i+1, i); if(flag[digists[i]]==1) break; flag[digists[i]]=1; }

        //计算第2部分 for(int i=1; i<=numofdigist_-1; i++){ int tmp=9; for(int j=1; j<i; j++) tmp *= 9-j+1; res_+=tmp; } return n-1-res_; }
  • 相关阅读:
    OSI结构和TCP/IP模型
    将[4,3,2,5,4,3]分割成[4,3,2]、[5,4,3]两个List的算法
    Mybatis增加对象属性不增加mapper.xml的情况
    以脚本方式直接执行修改密码的passwd命令
    Raphael的鼠标over move out事件
    Raphael的Braille例子
    Raphael的set使用
    Raphael的transform用法
    Raphael的text及对齐方式
    Raphael初始化,path,circle,rect,ellipse,image
  • 原文地址:https://www.cnblogs.com/jasonlixuetao/p/10585527.html
Copyright © 2020-2023  润新知