剑指offer(C++)-JZ43:整数中1出现的次数(算法-其他)

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

题目描述:

输入一个整数 n ,求 1~n 这 n 个整数的十进制表示中 1 出现的次数
例如, 1~13 中包含 1 的数字有 1 、 10 、 11 、 12 、 13 因此共出现 6 次

注意:11 这种情况算两次

数据范围:1≤n≤30000 

进阶:空间复杂度O(1)  ,时间复杂度O(logn) 

示例:

输入:

13

返回值:

6

解题思路:

本题考察算法思维。两种解题思路:

1)按位统计法

       将数字拆解,按位数统计1出现的次数。举例说明其中的规律。

       假设数字有32134。

       分析个位数出现1的次数:由3213个10和1个4组成,每个10里面就有1个1(只看个位),而4又大于1,所以还会出现1次个位为1的数字。

       分析十位数出现1的次数:由321个100和1个34组成,每个100里面就有10个1(只看十位),从10到19,而34大于19,说明还会出现10次十位为1的数字。

       分析百位数出现1的次数:由32个1000和1个134组成,每个1000里面就有100个1(只看百位),从100到199,而134小于199,说明还会出现35次百位为1的数字,即100到134。

       基于上述规律列出每位数出现次数的公式:bitcount = n / (b * 10) * b + min(max(n % (b * 10)- b + 1, (long long)(0)), b)。

       其中n为数字,b为当前位数,下面用百位数分析举例。n / (b * 10) 计算出当前位数高一级位的数量,*b表示对应1的数量,即有32个1000,32个1000就说明有32*100个1;max(n % (b * 10)- b + 1, (long long)(0))用来判断余出来的部分134是否大于100,如果换成一个小于100的数,那就取0,大于100的数就取超出100的部分,比如134就是100到134,共35个数;后面的min,是为了对超出100的部分做限制,假设134是234,那应该100到199最多100个数而不是235个数。

       该算法时间复杂度为O(log10 n),与位数相关,常数级变量,本题的理想解法。

2)暴力循环

       循环所有数字,对每个数字的所有位数也进行循环。该算法时间复杂度为O(nlog10 n)。

测试代码:

1)按位统计法

class Solution {
public:// 统计1出现的次数int NumberOf1Between1AndN_Solution(int n) {int count = 0;long long b = 1;// b代表位数,从1到10到100,以此类推直到超过nwhile(b <= n){// 假设数字32134// 分析个位数出现1的次数:由3213个10和1个4组成,每个10里面就有1个1(只看个位),而4又大于1,所以还会出现1次个位为1的数字// 分析十位数出现1的次数:由321个100和1个34组成,每个100里面就有10个1(只看十位),从10到19,而34大于19,说明还会出现10次十位为1的数字// 分析百位数出现1的次数:由32个1000和1个134组成,每个1000里面就有100个1(只看百位),从100到199,而134小于199,说明还会出现35次百位为1的数字,即100到134// 基于上述规律,可以列出下式// 后半段的min和max是为了判断后面余的那部分对应位数出现次数count += n / (b * 10) * b + min(max(n % (b * 10)- b + 1, (long long)(0)), b);b *= 10;}return count;}
};

2)暴力循环

class Solution {
public:// 统计1出现的次数int NumberOf1Between1AndN_Solution(int n) {int count = 0;// 循环所有数字for(int i = 1; i <= n; ++i){// 循环每个数字的所有位数for(int j = i; j > 0; j /= 10){if(j % 10 == 1){count++;}}} return count;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/217906.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SparkSQL之Optimized LogicalPlan生成过程

经过Analyzer的处理&#xff0c;Unresolved LogicalPlan已经解析成为Analyzed LogicalPlan。Analyzed LogicalPlan中自底向上节点分别对应Relation、Subquery、Filter和Project算子。   Analyzed LogicalPlan基本上是根据Unresolved LogicalPlan一对一转换过来的&#xff0c;…

Python 测试框架 Pytest 的入门

简介 pytest 是一个功能强大而易于使用的 Python 测试框架。它提供了简单的语法和灵活的功能&#xff0c;用于编写和组织测试代码。 1、简单易用&#xff1a;pytest 的语法简洁明了&#xff0c;使得编写测试用例更加直观和易于理解。它使用 assert 语句来验证预期结果&#x…

个体卫生室电子处方操作流程,私人诊所用什么电子处方系统软件,佳易王诊所电子处方软件配方模板如何设置

个体卫生室电子处方操作流程&#xff0c;私人诊所用什么电子处方系统软件&#xff0c;佳易王诊所电子处方软件配方模板如何设置 1、一般电子处方系统的操作流程为&#xff1a;由医师使用软件开电子处方&#xff0c;打印后核对信息医师签字&#xff0c;然后由药剂师审核单据&am…

字符串转换成十进制整数

编程要求 输入一个以#结束的字符串&#xff0c;本题要求滤去所有的非十六进制字符&#xff08;不分大小写&#xff09;&#xff0c;组成一个新的表示十六进制数字的字符串&#xff0c;然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”&#xff0c;则…

map和set的底层结构 --- AVL树的实现(万字图文详解)

AVL树的实现 底层结构1. AVL的概念2. AVL树节点的定义3. AVL树的插入分析 4. AVL树的旋转4.1 新节点插入较高右子树的右侧---右右&#xff1a;左单旋4.2 新节点插入较高左子树的左侧---左左&#xff1a;右单旋4.3 新节点插入较高右子树的左侧---右左&#xff1a;先右单旋再左单…

Oracle 最终抛弃了 Sun !

随着 Solaris 团队的彻底完蛋&#xff0c;看起来 Sun 微系统公司最终连块骨头都没剩下。 来自前 Sun 社区的消息表明&#xff0c;一月份的传闻&#xff08;Oracle 裁员 450 人&#xff09;成为了现实&#xff0c;上周五&#xff0c;Oracle 裁掉了 Solaris 和 SPARC 团队的核心员…

【键盘变成了快捷键,怎么办?】

**最便捷的操作&#xff1a;**拔掉键盘有线插头&#xff0c;将键盘驱动进行卸载&#xff0c;重新插上键盘即可 键盘驱动如何卸载: 以win10为例&#xff0c;点击开始菜单栏选择设置 选择左上角系统 选择系统中&#xff0c;点击最下方关于&#xff0c;点击右侧的设备管理器 选…

AJAX技术-04-- 跨域说明

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1 同源策略同源策略介绍规定要求 请求协议://域名:端口号 关于同源策略练习关于同源策略总结 2.JSONPJSONP原理说明关于JSONP优化 3.CORS介绍介绍不允许跨域说明跨域…

python_接口自动化测试框架

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

js中map和forEach的区别

forEach只是遍历数组的元素&#xff1b;map映射遍历&#xff0c;除了遍历数组的元素&#xff0c;还会返回一个新的数组。map本身是映射的意思。 若我们平时开发中只是遍历元素的话&#xff0c;用forEach&#xff0c;千万别用map。 注意&#xff1a; 他们俩若遍历的数组元素是基…

yolo系列中的一些评价指标说明

文章目录 一. 混淆矩阵二. 准确度(Accuracy)三. 精确度(Precision)四. 召回率(Recall)五. F1-score六. P-R曲线七. AP八. mAP九. mAP0.5十. mAP[0.5:0.95] 一. 混淆矩阵 TP (True positives)&#xff1a;被正确地划分为正例的个数&#xff0c;即实际为正例且被分类器划分为正例…

php订单发起退款(余额和微信支付)

index.html <a class="btn btn-danger btn-change btn-tuikuan btn-disabled" href="javascript:;"><i class="fa fa-tuikuan"></i> 订单退款</a>-->order.js // 为表格绑定事件Table.api.bindevent(table);//退款…