概述
题目描述
求出1~ 13的整数中1出现的次数,并算出100~ 1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
有一种把数字拆成数组,再循环判断数组中有没有1的思路,个人不推荐,复杂度太高。下面两种都是基于规律得到的。
解题思路—基础版:(在牛客网上看到这个大佬的解释特别清晰,在此借鉴!)
设N = abcde ,其中abcde分别为十进制中各位上的数字。
如果要计算百位上1出现的次数,它要受到3方面的影响:百位上的数字,百位以下(低位)的数字,百位以上(高位)的数字。
① 如果百位上数字为0,百位上可能出现1的次数由更高位决定。比如:12013,则可以知道百位出现1的情况可能是:100 ~ 199,1100 ~ 1199,2100 ~ 2199,… 11100~11199,一共1200个。可以看出是由更高位数字(12)决定,并且等于更高位数字(12)乘以当前位数(100)。
② 如果百位上数字为1,百位上可能出现1的次数不仅受更高位影响还受低位影响。比如:12113,则可以知道百位受高位影响出现的情况是:100 ~ 199,1100 ~ 1199,2100 ~ 2199,…,11100~11199,一共1200个。和上面情况一样,并且等于更高位数字(12)乘以当前位数(100)。但同时它还受低位影响,百位出现1的情况是:12100 ~12113,一共114个,等于低位数字(113)+1。
③ 如果百位上数字大于1(2 ~ 9),则百位上出现1的情况仅由更高位决定,比如12213,则百位出现1的情况是:100 ~ 199,1100 ~ 1199,2100 ~ 2199,…,11100 ~ 11199, 12100~12199,一共有1300个,并且等于更高位数字+1(12+1)乘以当前位数(100)。
解题思路—精简版:(在牛客网上还看到一个大佬分享的代码,实在是太优美,必须借鉴记录一下)
其实算法核心思想都是一样的,但可能直接看代码会有点懵,在这里贴一小段大佬的解释,看完就能理解
现在说十位数,十位数上出现1的情况应该是10-19,依然沿用分析个位数时候的阶梯理论,我们知道10-19这组数,每隔100出现一次,这次我们的阶梯是100,例如数字317,分析有阶梯0-99,100-199,200-299三段完整阶梯,每一段阶梯里面都会出现10次1(从10-19),最后分析露出来的那段不完整的阶梯。我们考虑如果露出来的数大于19,那么直接算10个1就行了,因为10-19肯定会出现;如果小于10,那么肯定不会出现十位数的1;如果在10-19之间的,我们计算结果应该是k - 10 + 1。例如我们分析300-317,17个数字,1出现的个数应该是17-10+1=8个。
那么现在可以归纳:十位上1出现的个数为:
• 设k = n % 100,即为不完整阶梯段的数字
• 归纳式为:(n / 100) * 10 + (if(k > 19) 10 else if(k < 10) 0 else k - 10 + 1)
Java解题—基础版
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int i = 1, count =0;
while(n/i!=0){
int before = n/i/10;
int after = n%i;
int current = (n/i)%10;
if(current==0)
count += before * i;
else if(current==1)
count += before * i + 1 + after;
else
count += (before+1) * i;
i *= 10;
}
return count;
}
}
Java解题—精简版
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
if(n <= 0)
return 0;
int count = 0;
for(long i = 1; i <= n; i *= 10){
long diviver = i * 10;
count += (n / diviver) * i + Math.min(Math.max(n % diviver - i + 1, 0), i);
}
return count;
}
}
最后
以上就是灵巧糖豆为你收集整理的剑指Offer-整数中1出现的次数(从1到n整数中1出现的次数)的全部内容,希望文章能够帮你解决剑指Offer-整数中1出现的次数(从1到n整数中1出现的次数)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复