![](https://img2020.cnblogs.com/blog/1517575/202101/1517575-20210122083449092-213456866.png)
思路分析
最简单的做法就是一位一位数字取出,看看是否为1
取数
cpp
class Solution {
public:
int numberOf1Between1AndN_Solution(int n) {
int s = 0;
for(int i=1;i<=n;i++){
int t =i;
while(t){
if(t%10==1)s+=1;
t/=10;
}
}
return s;
}
};
python
class Solution(object):
def numberOf1Between1AndN_Solution(self, n):
"""
:type n: int
:rtype: int
"""
s = 0
for i in range(1,n+1):
t = i
while t:
if t%10==1:s+=1
t //=10
return s
高低位
按位来进行计算,分为中间位,前位,和后位,分情况进行计算,循环中间位的值
以ab c def为例,中间位为c
(1) c = 1 则个数 += (ab - 1) * 1000(def位数)
(2) 前位取ab c = 0,则不加
c = 1 则个数 += def + 1
c > 1 则个数 += 1000(def位数)
自己可举详细例子进行尝试 例如12
(1) 中间位 = 1 前位为0,后位为2 则个数 += 2 + 1 = 3 这里 c = 1的情况
(2)中间位 = 2 前位为1,后位为0 则个数 += 1 + 1 = 2 这里(ab - 1) = 0 一种情况 还有一种c > 1 的情况
总数即为 5
每次就是考虑c这个位置.
首先
res += (0~ab-1)*t
高位=ab
1) c=0: 那么就没有情况了,因为只考虑c位
2) c=1: 低位可以取 0~right,有 right+1个
3) c>1: 那么只有c=1这一种情况,那么就只能加上t,也就是(0~999)
cpp
class Solution {
public:
int numberOf1Between1AndN_Solution(int n) {
vector<int> nums;
while(n)nums.push_back(n%10),n/=10;
int res=0;
for(int i=nums.size()-1;i>=0;i--){
int left=0,right=0,t=1;
for(int j=nums.size()-1;j>i;j--) left = left*10+nums[j];
for(int j=i-1;j>=0;j--)right = right*10 + nums[j],t*=10;
res += left * t;
if(nums[i]==1)res += right+1;
else if(nums[i]>1) res += t;
}
return res;
}
};
python
class Solution(object):
def numberOf1Between1AndN_Solution(self, n):
"""
:type n: int
:rtype: int
"""
res = 0
nums = []
while n:
nums.append(n%10)
n//=10
nums = nums[::-1]
for i,x in enumerate(nums):
left,right,t=0,0,1
for j in range(i):
left = left*10 + nums[j]
for j in range(i+1,len(nums)):
right = right*10 + nums[j]
t *=10
res += left * t
if nums[i]==1 :res += right+1
elif nums[i]>1 :res+=t
return res