前言
众所周知,《剑指offer》是一本“好书”。
如果你是个算法菜鸡(和我一样),那么最推荐的是先把剑指offer的题目搞明白。
对于剑指offer题解这个系列,我的写作思路是,对于看过文章的读者,能够做到:
- 迅速了解该题常见解答思路(偏门思路不包括在内,节省大家时间,实在有研究需求的人可以查阅其它资料)
- 思路尽量贴近原书(例如书中提到的面试官经常会要求不改变原数组,或者有空间限制等,尽量体现在代码中,保证读者可以不漏掉书中细节)
- 尽量精简话语,避免冗长解释
- 给出代码可运行,注释齐全,关注细节问题
- 代码能够通过牛客网在线编程《剑指offer》测试
《剑指offer题解》系列
你可以通过以下两种途径查看《剑指offer题解》系列:
- 关注我的公众号:Rude3Knife,点击公众号下方:剑指offer题解
- 剑指offer题解专栏(CSDN)
题目介绍
求出1 ~ 13的整数中1出现的次数,并算出100 ~ 1300的整数中1出现的次数?为此他特别数了一下1 ~ 13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
解题思路
方法一:递归每个数字
思路
思路很简单,写个for循环,从1到n,在循环体中判断这个数包含了多少个1
复杂度O(nlogn),面试官不怎么开心呢。。
方法二:找规律
思路
思路解释参考:
https://www.nowcoder.com/profile/3371548/codeBookDetail?submissionId=16319486
设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)。
代码
public int NumberOf1Between1AndN_Solution(int n) {//1的个数int count = 0;//当前位int i = 1;int current, after, before;while((n/i)!= 0){//高位数字current = (n/i)%10;//当前位数字before = n/(i*10);//低位数字after = n-(n/i)*i;//如果为0,出现1的次数由高位决定,数量等于高位数字 * 当前位数if (current == 0) {count += before * i;} else if(current == 1) {//如果为1,出现1的次数由高位和低位决定,高位*当前位+低位+1count += before * i + after + 1;} else{//如果大于1,出现1的次数由高位决定,(高位数字+1)* 当前位数count += (before + 1) * i;}//前移一位i = i*10;}return count;
}
总结
此题思考再三,想分析作者为什么要出此题,该题出现在优化时间和空间效率大类中,作者主要是想让同学们运用逻辑推理,想到时间上更优化的解法。
《剑指offer题解》系列
你可以通过以下两种途径查看《剑指offer题解》系列:
- 关注我的公众号:Rude3Knife,点击公众号下方:剑指offer题解专栏
- 剑指offer题解专栏(CSDN)
关注我
我是一名后端开发。主要关注后端开发,数据安全,爬虫等方向。微信:yangzd1102
Github:@qqxx6661
个人博客:
- CSDN:@qqxx6661
- 知乎:@Zhendong
- 简书:@蛮三刀把刀
- 掘金:@蛮三刀把刀
原创博客主要内容
- Java知识点复习全手册
- Leetcode算法题解析
- 剑指offer算法题解析
- SpringCloud菜鸟入门实战系列
- SpringBoot菜鸟入门实战系列
- Python爬虫相关技术文章
- 后端开发相关技术文章
个人公众号:Rude3Knife
如果文章对你有帮助,不妨收藏起来并转发给您的朋友们~