目录
- class Solution {
- public:
- int NumberOf1Between1AndN_Solution(int n) {
- int res=0;
- for(int i=1;i<=n;i++)
- {
- int n=i;
- while(n)
- {
- if(n%10==1) res++;
- n/=10;
- }
- }
- return res;
- }
- };
核心:分析第d位的情况出现数字1的数的个数
具体的描述:
假设现在的数字是abcdefg
1. d== 0; 那么d的左边可以选取 0 ~ abc-1,共abc个数。不能取abc这个点是因为此时这里d为0,不会出现1.那么d的右边可以取0~999。因为左边最大是abc-1,所以右边取999也不会比原来的数大。
2, d == 1; 此时,d的左边可以取0~abc;在0~abc-1的区间,右边可以取0~999;而在abc这个点,右边只能取0~efg,共efg+1个点。所以分开算的话:abc1000 + (efg+1);
3,d > 1;此时,d的左边可以取0~abc,右边可以取0~999;共计(abc+1)1000;然后求以上三者的和
![]()
注意一:通常用一个vector数组存储数位,例如vector
nums 注意二:数位的数组在存储后通常要reverse,方便遍历的时候从习惯手写数字的高位开始遍历。
- class Solution {
- public:
- int NumberOf1Between1AndN_Solution(int n) {
- vector<int> nums;//存储数位
- while(n) {nums.push_back(n%10),n/=10;}
- int res=0;
- reverse(nums.begin(),nums.end());
- for(int i=nums.size()-1;i>=0;i--)//从手写的习惯位开始遍历
- {
- int d=nums[i];//表示第i位是多少
- int left=0,right=0,p=1;
- for(int j=0;j
- {
- left=left*10+nums[j];
- }
-
- for(int j=i+1;j
size();j++) - {
- right=right*10+nums[j];
- p=p*10;
- }
-
- if(d==0) res+=left*p;
- else if(d==1) res+=left*p+right+1;
- else res+=(left+1)*p;
- }
- return res;
- }
- };