zoukankan      html  css  js  c++  java
  • 整数中 1 出现的次数(从 1 到 n 整数中 1 出现的次数)


    求出 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;
        }
    }
    

  • 相关阅读:
    如何实现asp.net页面的美观性?
    关于UpdatePanel和页面刷新的问题
    由windows server2012 想起
    新手看SEO网站优化
    转载Web 2.0 新名词:Widget
    由“美图秀秀”软件的网站,看网站的生存模式
    关于团队合作的一点认识
    对新网好失望,郁闷中
    程序员度量:改善软件团队的分析学
    了解天才科学家的研究历程,了解知识贴近生活的一面,学习就是一件充满乐趣的事儿
  • 原文地址:https://www.cnblogs.com/Yee-Q/p/13828625.html
Copyright © 2011-2022 走看看