zoukankan      html  css  js  c++  java
  • 剑指Offer对答如流系列

    面试题43:从1到n整数中1出现的次数

    题目描述

    输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。

    例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。

    问题分析

    最容易想到的思路是通过对10求余数判断整数的个位数字是不是1。代码书写也很简单,但是如果输入的整数n比较大的时候,会有大量的运算。

    1是由于数字递增出现的,而十进制影响这种出现的周期性。这本身肯定存在规律,重要的是耐心寻找,不要妄想一次性就找出来,下面的规律要比《剑指Offer》书上提到的更好点。

    我们以12043来进行分析。我们从个位开始,一直到最高位,统计每一位上的1出现的次数。

    我们将数字拆分成三部分,高位high,当前位cur和低位low

    1. 当当前位为个位的时候,high是1204、cur是3、low不存在,设置为0。个位数为1的情况有00001 - 12041,一共是1204+1种情况。

    2. 当当前位为十位的时候,high是120、cur是4、low是3,十位数字为1的情况:先考虑低位有 00010 - 00019(10种)、再综合考虑:0001X-1201X,一共是(120+1)* 10种情况。

    3. 当当前位为百位的时候,high是12、cur是0、low是43,百为数字为1的情况:先考虑低位有00100 - 00199(100种),再综合考虑:000XXX-110XXX,一共是(11+1)*100种情况,注意因为不存在121XXX,最高为111XXX

    4. 当当前位为千位的时候,high为1、cur是2、low是043,千位数字为1的情况:先考虑低位有01000 - 01999(1000种),在综合考虑:01XXXX - 11XXXX,一共是(1+1)*1000种情况

    5. 当当前位为万位的时候,high是0、cur是1、low是2043,万位数字为1的情况:先考虑低位有10000-12043,一共是2043+1种情况。

    当cur为0和1的时候需要特殊处理,其他值的时候常规处理。

    再举一个数字21034

    1. 当前位的数字等于0时,例如n=21034,在百位上的数字cur=0,百位上是1的情况有:00100-00199,01100-01199,……,20100~20199。一共有21*100种情况,即high*100;

    2. 当前位的数字等于1时,例如n=21034,在千位上的数字cur=1,千位上是1的情况有:01000-01999,11000-11999,21000-21034。一共有2*1000+(34+1)种情况,即high*1000+(low+1)。

    3. 当前位的数字大于1时,例如n=21034,在十位上的数字cur=3,十位上是1的情况有:00010-00019,……,21010-21019。一共有(210+1)*10种情况,即(high+1)*10。

    对于整数n,其位数一共有lgn个,所以时间复杂度为O(logn)。

    问题解答

        public int NumberOf1Between1AndN(int n) {
            int count=0;
            // i代表位数
            for(int i=1;i<=n;i*=10){
                //高位数字
                int high=n/(i*10);
                //低位数字
                int low= n%i;
                //当前位数字
                int cur=(n/i)%10;
    
                if(cur==0) {
                    count+=high*i;
                } else if (cur==1){
                    count+=high*i+(low+1);
                } else {
                    count+=(high+1)*i;
                }
            }
            return count;
        }
    
  • 相关阅读:
    【转载】loadrunner使用system()函数调用Tesseract-OCR识别验证码遇到的问题
    实现LoadRunner多个场景的顺序执行(命令行)
    BAT批处理(一)
    BAT批处理(二)
    BAT批处理(五)
    BAT批处理(六)
    BAT批处理(三)
    BAT批处理(四)
    DOS工具
    python3.0与2.x之间的区别
  • 原文地址:https://www.cnblogs.com/JefferyChenXiao/p/12246500.html
Copyright © 2011-2022 走看看