剑指offer面试题43:1-n整数中1出现的次数(Java 实现)

题目:输入一个整数n,求 1-n 这 n 个整数的十进制表示中 1 出现的次数。例如,输入12, 1-12 中这些整数中包含1的数字有1、10、11 和 12, 1 一共出现 5 次。

方法一:暴力法,时间复杂度为 O(nlogn)

直接循环遍历求出 n 个数中每一个数包含 1 的次数,然后累加起来。

//方法一:暴力法
    public int NumberOf1Between1AndN_Solution(int n){
        int number = 0;
        for (int i=1; i <= n; i++){
            number = number + numbersOf1(i);
        }
        return number;
    }

    private int numbersOf1(int n) {
        int numbers = 0;
        while (n > 0){
            if (n % 10 == 1){
                numbers++;
            }
            n = n/10;
        }
        return numbers;
    }

方法二:从数字规律入手,时间复杂度为O(logn)。

思路:参考 这篇博客

 public int NumberOf1Between1AndN_Solution(int n){
        if(n<1) return 0;

        int count = 0; //计数器
        int base = 1;  //从个位数开始基数为1,十位数的基数为10...
        int round = n;

        while(round>0){
            //表示十进制的每一位,从各位数开始
            int weight = round % 10;
            
            //表示每一次weight位上的数要从0-9变换多少个轮回
            round = round / 10;      
            
            //当weight位上为0的时候
            count =  count + round * base;
            
            if(weight==1){
                count= count + (n % base)+1;
            }
            else if(weight>1){
                count= count + base;
            }
             //下一位的基数为前一位基数的十倍
            base= base * 10; 
        }
        return count;
    }

 

你可能感兴趣的:(剑指offer)