剑指offer 17. 打印从1到最大的n位数

题目描述

输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

示例 1:

输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]

说明:

用返回一个整数列表来代替打印
n 为正整数

解法1(不考虑大数问题)

使用Math.pow()函数即可

解法2(考虑大数问题)

题解转载自简书:SunChaser_lilu
思路:当输入n很大时,使用int或long都会溢出。需要考虑大数问题。
可以借用字符串或数组表示大数。首先把字符串中的每一个数字初始化为’0’,然后每一次为字符串表示的数加1,再打印出来。因此,我们只需要做两件事:一是在字符串表示的数字上模拟加法;二是把字符串表示的数字打印出来。
在模拟加法的过程中需要判断是否已经到了最大的n位数,如果使用库函数则时间复杂度为O(n)。在加法的过程中如果字符串的第一个字符产生了进位,则已经到达了最大的n位数。可以实现O(1)时间判断是否已经达到了最大的n位数。
打印字符串表示的数字时,字符串开始的0不必打印。例如’068’打印68

increment函数,若发生进位则一直进行for循环,直到不产生进位则break。如果i为0(即到了最高位)还发生了进位,则设置isOverflow为true,并返回至主函数的while判断。

class Solution {
    public int[] printNumbers(int n) {
        int[] res = new int[n];
        StringBuilder str = new StringBuilder();
        //初始化一个全为’0‘的字符串
        for(int i =0;i<n;i++){
            str.append('0');
        }
        while(!increment(str)){
            //去除前面的0然后打印
            int index = 0;
            //index最后停留在第一个非0的位置
            //str.chaAt()得到的是字符
            while(str.charAt(index)=='0'&&index<str.length()-1){
                index++;
                }
                System.out.println(str.toString().substring(index));
            }
        return res;
    }

   public boolean increment(StringBuilder str){
       boolean isOverflow = false;
       for(int i=str.length()-1;i>=0;i--){
           //给该数字+1
           char s = (char)(str.charAt(i)+1);
           //如果s>'9',则发生了进位,给str.charAt(i)+1,不退出循环
           //i++后str.charAt(i)+1(相当于进位)
           if(s>'9'){
               //替换str中的字符要用“ ”(String类型而不是char类型)
               str.replace(i,i+1,"0");
               if(i==0){
                   isOverflow = true; 
               }
           }
           //如果未发生进位,则退出此次循环,得到一个新的str值
           else{
               //替换str中的字符要用String类型而不是char类型
               str.replace(i,i+1,String.valueOf(s));
               break;
           }
       }
       return isOverflow;
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章