ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

整数中 1 出现的次数(从 1 到 n 整数中 1 出现的次数)

2020-10-16 20:32:01  阅读:197  来源: 互联网

标签:10 int 56 整数 次数 百位 100 出现



求出 1 ~ 13 的整数中 1 出现的次数,并算出 100 ~ 1300 的整数中 1 出现的次数?可以发现 1 ~ 13 中包含 1 的数字有 1、10、11、12、13,因此共出现 6 次。现需要把问题更加普遍化,可以很快的求出任意非负整数区间中 1 出现的次数(从 1 到 n 中 1 出现的次数)


解题思路

设定整数点(1、10、100、1000、10000)分别对应 n 的个位、十位、百位、千位、万位,我们要做的就是:考虑每一位出现 1 的情况,算出各自符合题意的数的数量,并进行相加,就能得出想要的结果。

现以整数点 100 为例,使用 100 对 n 进行分割,高位为 n/100,低位为 n%100

考虑三种情况:

  • 以 31456 为例,百位对应的数 4 >= 2,此时高位 a = 314,低位 b = 56,因为 4 >= 2,所以肯定会有百位为 1 的情况,此时无论其他位的数是多少,都将满足题意。高位可以取 32 种情况(0 ~ 31),低位则总是 100 个连续的点,因此共有 (a/10 + 1)*100 个数
  • 以 31156 为例,百位对应的数 1 == 1,此时高位 a = 311,低位 b = 56,因为百位已经是 1,此时无论其他位的数是多少,都将满足题意。高位的取值要分情况,当最高两位范围是 0 ~ 30 时,和上一条一样;当 a = 311(取 31) 时,则对应的低位只有 0 ~ 56,共 b + 1 次,因此总共有 (a/10)*100 + (b + 1)
  • 以 31056 为例,百位对应的数为 0,此时高位 a = 310,低位 b = 56,百位为 0,所以高位的前两位只能去 0 ~ 30,这样百位才能取 1,因此总共有 (a/10)*100

综合以上三种情况,我们可以得出:

  • 当百位 == 0 或 >= 2 时,有 (a+8)/10 次包含所有 100 个点(之所以补 8,是因为当百位为 0,则 a/10 == (a+8)/10,当百位 >= 2,补 8 会产生进位位,效果等同于 (a/10+1))
  • 当百位 == 1,即 (a%10==1),则需要增加局部点 b+1
public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int count = 0;
        long split = 1;
        for(int i = 1; i <= n; i *= 10) {
            int a = n/i, b = n%i;
            count = count + ((a+8)/10)*i + ((a%10 == 1) ? (b + 1) : 0);
        }
        return count;
    }
}

标签:10,int,56,整数,次数,百位,100,出现
来源: https://www.cnblogs.com/Yee-Q/p/13828625.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有