题目大意:
在[1,n]中,统计 所有 数位上包含的1数字,总共1的个数。比如 [1,11] 数位包含1的数字有: 1 10 11 总共有1 + 1 + 2 = 4 个1.
解题思路:
这题我们需要逐个数字位置上思考,个位对答案的贡献,十位对答案的贡献。。。
这里有一个key,我们这样最后答案的组成。比如数字 n = 2134:那么从个位开始看:所有的数字的组成可以看为 [0,2130] U [2131,2134],这样看有什么好处呢?
[0,2130]这部分对答案的贡献就是 213 个 1,得到个位的贡献的左半部分了!ans+=213. 那么我们再看 2131 2132 2133 2134,其中2131中的个位是1.所以 ans+= 1.
同样对于十位对答案的贡献。我们发现可以拆分为[0,2100] U [2101,2134].
左半拆分 ans+=21 * 10(因为有21个可能你的十位是可以放置1的,同时每次放置在这里时答案就会+10. 所以是 21 * 10)
右半拆分 ans+= 10.
每一个数位一直讨论就可以了
class Solution {
public:
vector<int> mv;
int ans;
int NumberOf1Between1AndN_Solution(int n)
{
int tmpn = n;
ans = 0;
while(tmpn){
mv.push_back(tmpn%10);
tmpn/=10;
}
int div = 10;
int mul = 1;
for(int i = 0;i<(int)mv.size();i++){
ans += n/div*mul;
if(mv[i]>1)ans+=mul;
else if(mv[i] == 1)ans+=(n%(int)pow(10,i)+1);
div*=10;
mul*=10;
}
return ans;
}
};