文章目录
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210328220303595.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pjejU1NjY3MTk=,size_16,color_FFFFFF,t_70)
其实有点类似与计数DP的思路。但是我觉着这个问题的思路还是非常的巧妙的值得学习。首先将一个数字分为了两个部分,比如123456
,高位high = 1234
, 低位low = 6
,当前位cur = 5
。额外有当前的位的数量级digit
;因为我们分析的是1的出现次数。那么有三种情况:
- 当前位置是小于x的。比如
123 0 7
,这个情况下,当前位出现一的情况是0010~12219
,只看高低位的话,000 0~1229
因此是1230
个。此时就是digit*high
- 当前位置等于x。比如
123 1 7
,此时当前位出现一的情况是00010~12317
,只看高低位的话,000 0~123 7
因此是1238
个。此时就是digit*high+low+1
- 当前位置大于x。比如
123 3 7
,此时当前位出现一的情况是00010~12319
,只看高低位的话,000 0~123 9
因此是1240
个。此时就是digit*(high+1)
因此代码就容易了
class Solution {
public int countDigitOne(int n) {
int digit = 1, res = 0;
int high = n / 10, cur = n % 10, low = 0;
while(high != 0 || cur != 0) {
if(cur == 0) res += high * digit;
else if(cur == 1) res += high * digit + low + 1;
else res += (high + 1) * digit;
low += cur * digit;
cur = high % 10;
high /= 10;
digit *= 10;
}
return res;
}
}