剑指Offer面试题12(Java版):打印1到最大的n位数

来源:互联网 发布:java实现zip解压 编辑:程序博客网 时间:2024/05/21 08:53

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

1、跳进面试官的陷阱

这个题目看起来很简单。我们看到这个问题后,最容易想到的办法是求出最大的n位数,然后用一个循环从1开始逐个打印。于是我们很容易写出下面的代码。

void print1ToMaxOfNDigits(int n){

        int number =1;

        int i =0;

        while(i++< n)

               number*=10;

         for(int i =1;i<number;++i)

                 System.out.println(i);

}

初看之下没有问题,但如果仔细分析这个问题,我们就能注意到面试官没有规定n的范围。当输入n很大的时候,我们求最大的n位数是不是用整型(int)或者长整型(long long)都会溢出?也就是说我们需要考虑大数问题。这是面试官在这道题里设置的一个大陷阱。


2、在字符串上模拟数字加法的解法:

经过前面的分析,我们很自然的想到解决这个问题需要一个大数。最常用的也是最容易的用字符串或者数组表达大数。接下来我们用数组来解决大数问题。

实现下面的代码:

/** *  */package swordForOffer;import java.util.ArrayList;import java.util.Iterator;/** * @author JInShuangQi * *         2015年7月31日 */public class E12Print1ToMaxOfNDigits {public void outPutOneToMaxNDigits(int n) {// 用nlist表示数n,nlist[0]表示n的最低位ArrayList<Integer> nlist = new ArrayList<Integer>();for (int i = 0; i < n; i++) {nlist.add(0);}increment(nlist);}// 使数字每次+1然后输出public void increment(ArrayList<Integer> nlist) {int carrybit = 0;boolean end = false;while (true) {for (int i = nlist.size() - 1; i >= 0; i--) {int digit = nlist.get(i);int sum = digit + carrybit;if (i == (nlist.size() - 1)) {sum += 1;}if (sum >= 10) {// 最高位产生进位,达到最大值,停止输出if (i == 0) {end = true;}sum = sum - 10;carrybit = 1;} else {carrybit = 0;}nlist.set(i, sum);}output(nlist);if (end) {break;}}}// 输出数字,将高位的0舍掉public void output(ArrayList<Integer> nlist) {Iterator<Integer> ite = nlist.iterator();int num;// 找到第一个为0的位置boolean first = false;while (ite.hasNext()) {if (first) {System.out.print(ite.next());continue;}if ((num = ite.next()) != 0) {first = true;System.out.print(num);}}System.out.println();}public static void main(String[] args) {E12Print1ToMaxOfNDigits test = new E12Print1ToMaxOfNDigits();test.outPutOneToMaxNDigits(2);}}


0 0