《劍指 Offer》面試題 12 考察大數問題處理能力:輸入 n,按順序打印從 1 到最大的 n 位十進制數(如 n=3 打印 1~999)。當 n 較大時,結果超出 long 範圍,必須使用字符串或數組模擬大數運算。
int[] 或 char[] 存儲每一位數字,下標 0 為最高位或最低位public class PrintOneToMaxNthDigits {
// 數組模擬 +1 操作,返回是否溢出(達到最大n位數)
public static boolean increment(int[] number) {
if (number.length == 0) throw new IllegalArgumentException("Invalid length");
boolean isOverflow = false;
int carry = 0;
for (int i = number.length - 1; i >= 0; i--) {
int sum = number[i] + carry;
if (i == number.length - 1) sum++; // 最低位 +1
if (sum >= 10) {
if (i == 0) {
isOverflow = true; // 最高位進位,結束
} else {
carry = 1;
number[i] = 0;
}
} else {
number[i] = sum;
break; // 無進位,提前結束循環
}
}
return isOverflow;
}
// 打印數組,跳過前導0
public static void printNumber(int[] number) {
boolean isBeginning = true;
for (int digit : number) {
if (isBeginning && digit != 0) isBeginning = false;
if (!isBeginning) System.out.print(digit);
}
System.out.println();
}
public static void print1ToMaxOfNDigits(int n) {
if (n <= 0) return;
int[] number = new int[n];
while (!increment(number)) {
printNumber(number);
}
}
public static void main(String[] args) {
print1ToMaxOfNDigits(3); // 打印 1 到 999
}
}
public class PrintOneToMaxNthDigitsRecursive {
public static void print1ToMaxOfNDigits(int n) {
if (n <= 0) return;
char[] number = new char[n];
// 最高位不能為 0,從 1-9 開始遞歸填充後續位
for (int i = 1; i <= 9; i++) {
number[0] = (char)('0' + i);
printRecursively(number, n, 0);
}
}
private static void printRecursively(char[] number, int length, int index) {
if (index == length - 1) {
printNumber(number);
return;
}
for (int i = 0; i <= 9; i++) {
number[index + 1] = (char)('0' + i);
printRecursively(number, length, index + 1);
}
}
private static void printNumber(char[] number) {
// 同數組版邏輯,跳過前導0(實際上最高位已非0)
StringBuilder sb = new StringBuilder();
boolean leading = true;
for (char c : number) {
if (leading && c == '0') continue;
leading = false;
sb.append(c);
}
System.out.println(sb.toString());
}
}
| 維度 | 數組迭代 | 字符串遞歸 |
|---|---|---|
| 空間複雜度 | O(n) | O(n) + 遞歸棧 O(n) |
| 棧溢出風險 | 無 | n 極大時可能 |
| 代碼直觀度 | 中等 | 高(全排列思路) |
| 性能 | 略優(無函數調用開銷) | 略低 |
| 擴展性 | 易於修改為大數加減乘除 | 天然適合全排列/組合問題 |