劍指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;
    }

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