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_; }

猜你喜欢

转载自www.cnblogs.com/jasonlixuetao/p/10585527.html