劍指Offer題目12:打印1到最大的n位數:輸入數字n,按順序打印出從1最大的n位十進制數(Java)

面試題12:輸入數字n,按順序打印出從1最大的n位十進制數。好比輸入3,則打印出一、二、3一直到最大的3位數即999。面試

Basic

凡是數字計算的,須要考慮大數場景,即溢出。數組

解決方案:改用字符串或字符數組來表達大數。bash

根據 ASCII 碼錶, 字符 '0'~'9' 都有對應的整數表示,從 '0' 到 '9' 加 1 遞增,所以有以下算術關係:app

字符和數字之間的轉換:charA - '0' = numOfCharAui

1 = '1' - '0'
2 = '2' - '0'
3 = '3' - '0'
···
9 = '9' - '0'
複製代碼

字符之間的減運算 <=> 整數之間的減運算。spa

'1' - '1' = 1 - 1 = 0
'9' - '8' = 9 - 8 = 1
複製代碼

解題思路

建立一個 StringBuilder 來拼接字符。3d

for循環,從個位加1算起,注意循環的中間變量進位的保存和賦值。code

代碼實現

public static void print1ToMax(int n) {
        if (n < 0) {
            return;
        }
        StringBuilder numStr = new StringBuilder();
        for (int i = 0; i < n; i++) {
            numStr.append('0');
        }

        while (isIncreasing(numStr, n)) {
            print(numStr);
        }
    }

    private static void print(StringBuilder sb) {
        int start = sb.length();
        // 找到第一個不爲0的索引
        for (int i = 0; i < sb.length(); i++) {
            if (sb.charAt(i) != '0') {
                start = i;
                break;
            }
        }
        // 若是全是0,就不會打印
        if (start < sb.length()) {
            System.out.print(sb.substring(start) + " ");
        }
    }

    private static boolean isIncreasing(StringBuilder numStr, int n) {
        int carry = 0;
        for (int i = n - 1; i >= 0; i--) {
            int singleNum = numStr.charAt(i) - '0' + carry;
            if (i == n - 1) {
                singleNum ++; //在個位上自增
            }

            if (singleNum == 10) {  //1. 若是有進位,則將當前位置爲0,對更大的下一位加1
                if (i == 0) { //若是已經到最大的那位還有進位,則說明已經溢出,退出整個打印流程
                    return false;
                } else {
                    numStr.setCharAt(i, '0');
                    carry = 1;
                }
            } else { //2. 若是沒有進位,則退出當前這個 for 循環,執行打印
                numStr.setCharAt(i, (char) (singleNum + '0'));
                break;
            }
        }
        return true;
    }
複製代碼

總結

暫無。cdn

相關文章
相關標籤/搜索