양의 정수 N이 있다고 가정하고 반복되는 숫자가 1개 이상인 N보다 작거나 같은 양의 정수의 수를 찾아야 합니다.
따라서 입력이 99와 같으면 11, 22, 33, 44, 55, 66, 77, 88, 99와 같은 숫자가 있으므로 출력은 9가 됩니다.
이 문제를 해결하기 위해 다음 단계를 따릅니다. −
-
함수 A()를 정의하면 m, n,
가 필요합니다.-
렛 :=1
-
initialize i :=0의 경우, i
-
렛 :=렛 * m
-
(m 1 감소)
-
-
리턴 렛
-
-
주요 방법에서 다음을 수행하십시오 -
-
배열 arr 정의
-
i :=N + 1 초기화의 경우 i> 0일 때 i :=i / 10을 업데이트합니다. -
-
인덱스 i mod 10에 있는 arr의 첫 번째 요소를 arr에 삽입
-
-
ret :=0
-
n :=arr의 크기
-
initialize i :=1의 경우, i
-
렛 :=렛 + 9 * A(9, i - 1)
-
-
방문한 한 세트 정의
-
initialize i :=0의 경우, i
-
숫자 :=arr[i]
-
j를 초기화하기 위해 :=(i가 0과 같으면 1, 그렇지 않으면 0), j <자리일 때 업데이트(j를 1만큼 증가), −
-
j가 방문 중인 경우 -
-
다음 부분은 무시하고 다음 반복으로 건너뜁니다.
-
-
렛 :=렛 + A(9 - i, n - i - 1)
-
-
숫자가 방문한 경우 -
-
루프에서 나오세요
-
-
방문에 숫자 삽입
-
-
리턴 N - 렛
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
예시
#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