题目链接
连提示都提示要注意溢出,所以还是记得用long long
难得独立做出来一道“困难”题,总要记录一下qwq
我的思路和下述思路相同,所以直接引用人家的语言记录吧
发现规律的过程是首先想到对每一位有多少1进行统计,判断每一位有多少1时,一开始只考虑了高位的情形,笼统的认为贡献了(高位+1)*base, 如11111,判断百位多少个1就是(11+1)*100,之所以+1是考虑到从0到11变化是12个100,但是多举几个例子后发现这个+1并不是总成立,因此想到了还需要看低位,事实上这个+1也是低位贡献了base次的结果,进而联想到对本位进行0 1 >1的判断决定低位的贡献,用11111验证结果正确。
详细解释见代码:
class Solution {
public:
int countDigitOne(int n) {
int tmp=n;
long long base=1;
int res=0;
while(tmp){//逐位去判断,即每一位各含多少1
res=res+tmp/10*base;//高位对本位的贡献,如12011,判断百位,高位贡献了12*100
int low=tmp%10;//low就是正在判断的本位,接下来要加上剩下的低位的贡献
//本位low=0,剩余的低位对本位的1没贡献,如12011,判断百位有多少1,低位的11没贡献
if(low==1){
//本位low=1,低位对这一位的贡献就是低位有多少数字,如12111,判断百位有多少1,低位的11贡献了11+1次,从0计数
res=res+n%base+1;
}else if(low>1){
//本位大于1,贡献了1*base次,如12211,判断百位多少1,百位大于1了,说明剩下的低位从0-99变化100次,贡献base=100
res+=base;
}
tmp=tmp/10;
base=base*10;
}
return res;
}
};