给定正整数 N,返回小于等于 N 且具有至少 1 位重复数字的正整数。
示例 1:
输入:20
输出:1
解释:具有至少 1 位重复数字的正数(<= 20)只有 11 。
示例 2:
输入:100
输出:10
解释:具有至少 1 位重复数字的正数(<= 100)有 11,22,33,44,55,66,77,88,99 和 100 。
示例 3:
输入:1000
输出:262
提示:
1 <= N <= 10^9
解题思路:
class Solution {
public:
int numDupDigitsAtMostN(int N)
{
string s = to_string(N) ;
int n = s.size() ;
vector<vector<int>> arranged(10 , vector<int>(10,1)) ;
for(int i = 1 ; i < 10 ; ++i)
for(int j = 1 ; j <= i ; ++j) arranged[i][j] = arranged[i][j - 1] * (i + 1 - j) ;
int res = 0 ;
for(int i = 1 ; i < n ; ++i) res += 9 * arranged[9][i - 1] ;
unordered_set<int> visited ;
for(int i = 0 ; i < n ; ++i)
{
int m = s[i] - '0' , cnt = 0 ;
for(int j = (i == 0 ? 1 : 0) ; j < m ; ++j)
{
if(!visited.count(j)) cnt++ ;
}
cout<<"i:"<<i<<"; cnt:"<<cnt<<endl;
res += cnt * arranged[9 - i][n - 1 - i] ;
if(visited.count(m)) break ; //当m重复时应该退出;
if(i == n - 1 && !visited.count(m)) res++ ;
visited.insert(m) ;
}
return N - res ;
}
};