假设我们有一个正整数N,我们必须找到小于或等于N且具有至少1个重复数字的正整数。
因此,如果输入像99,那么输出将是9,因为我们有数字11、22、33、44、55、66、77、88、99。
为了解决这个问题,我们将遵循以下步骤-
定义一个函数A(),它将花费m,n,
ret:= ret *米
(将m减1)
ret:= 1
对于初始化i:= 0,当i <n时,更新(将i增加1),执行-
返回ret
从主要方法中执行以下操作-
定义数组arr
对于初始化i:= N + 1,当i> 0时,更新i:= i / 10,执行-
将索引为mod 10的arr的第一个元素插入arr
ret:= 0
n:= arr的大小
对于初始化i:= 1,当i <n时,更新(将i增加1),-
ret:= ret + 9 * A(9,i-1)
定义一组参观
对于初始化i:= 0,当i <n时,更新(将i增加1),执行-
从循环中出来
如果访问了j,则-
ret:= ret + A(9-i,n-i-1)
忽略以下部分,跳至下一个迭代
digit:= arr [i]
对于初始化j:=(如果i与0相同,则为1,否则为0),当j <digit时,更新(将j增加1),执行-
如果访问过数字,则-
将数字插入已访问
返回N-ret
让我们看下面的实现以更好地理解-
#include <bits/stdc++.h> using namespace std; class Solution { public: int A(int m, int n){ int ret = 1; for (int i = 0; i < n; i++) { ret *= m; m--; } return ret; } int numDupDigitsAtMostN(int N){ vector<int> arr; for (int i = N + 1; i > 0; i /= 10) { arr.insert(arr.begin(), i % 10); } int ret = 0; int n = arr.size(); for (int i = 1; i < n; i++) { ret += 9 * A(9, i - 1); } set<int> visited; for (int i = 0; i < n; i++) { int digit = arr[i]; for (int j = i == 0 ? 1 : 0; j < digit; j++) { if (visited.count(j)) continue; ret += A(9 - i, n - i - 1); } if (visited.count(digit)) break; visited.insert(digit); } return N - ret; } }; main(){ Solution ob; cout << (ob.numDupDigitsAtMostN(99)); }
99
输出结果
9