剑指offer之面试题12:打印1到最大的n位数

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

思路:看似很简单的一道题:

public static void Print1ToMaxOfDigits(int n){
        int number=1;
        for(int i=0;i<n;i++){
            number=number*10;
        }
        for(int j=1;j<number;j++){
            System.out.println(j);
        //上述代码存在问题,若n比较大,number可能会溢出,所以应考虑用字符串或者数组来存储
    }

先给出代码:

package com.su.biancheng;

import java.util.Arrays;

/** * @title Print1ToMaxOfDigits.java * @author Shuai * @date 2016-4-9下午4:22:24 */
public class Print1ToMaxOfDigits {
    public static void Print1ToMaxOfDigits(int n){
        /* int number=1; for(int i=0;i<n;i++){ number=number*10; } for(int j=1;j<number;j++){ System.out.println(j); } */
        //上述代码存在问题,若n比较大,number可能会溢出,所以应考虑用字符串或者数组来存储

        if(n<=0)
            return;
        char[] number=new char[n];
        //初始化每个字符都为'0'
        for(int i=0;i<number.length;i++){
            number[i]='0';
        }
        while(!Increment(number)){
            PrintNumer(number);
        }
        //System.out.println(number);

    }
    private static void PrintNumer(char[] number) {
        //从第一个不为'0'开始打印
        boolean isBeginning0=true;
        for(int i=0;i<number.length;i++){
            if(isBeginning0&&number[i]!='0'){
                isBeginning0=false;
            }
            if(!isBeginning0){
                System.out.print(number[i]);
            }
        }
        System.out.println();

    }
    private static boolean Increment(char[] number) {
        boolean isOverFlow=false;
        int iTakeOver=0;
        for(int i=number.length-1;i>=0;i--){
            int iSum=number[i]-'0'+iTakeOver;
            if(i==number.length-1){
                iSum++;//如果是0999...999,加1,最高位由'0'变为1,据此可判断是否已经加到最大值
            }
            if(iSum>=10){
                if(i==0){
                    isOverFlow=true;
                    //break;可加可不加,因为此时已经循环结束
                }
                else{
                    iSum-=10;
                    iTakeOver=1;
                    number[i]=(char) ('0'+iSum);
                }
            }
            else{
                number[i]=(char) ('0'+iSum);
                break;
            }
        }
        return isOverFlow;
    }
    public static void main(String[] args){
        int n=3;
        Print1ToMaxOfDigits(n);
    }
}
Note:
while(!Increment(number)){
    PrintNumer(number);
}
解释一下以上代码,它的作用是为了检查是否已经加到最大数字。

Increment(number)
为什么不直接调用字符串比较函数equal来判断是否已经到99..99?
因为equal函数要逐个比较,对于n位数,时间为O(n),加上外层循环while,时间为O(n^2)

能否O(1)时间内完成比较?
如果已经是最大数字,则加上1后:最高位变为0(数组的第一位),同时产生数组越界的标志(就是进位了,这里字符数组长度为)


PrintNumer(number);
为什么不直接使用System.out.println(number);
使用System.out.println(number);则打印出的格式是00..01,00..02,..,不符合习惯。所以希望把没用的前面的0去掉。
每个数都是字符数组存储的,我们想从前往后遍历,找到第一个不为0,然后开始打印即可。

思路二:数字排列
算上需要前面补0的,n位数每一位都是0-9排列,这样可以使用递归的思想,先构造第一位,然后构造下一位,当构造到n位时,打印输出

/** * */
package com.su.biancheng;

/** * @title Print1ToMaxOFDigits2.java * @author Shuai * @date 2016-4-9下午7:50:15 */
public class Print1ToMaxOFDigits2 {
    public static void Print1ToMaxOFDigits2(int n){
        if(n<=0)
            return;
        char[] number=new char[n];
        /*for(int i=0;i<number.length;i++){ number[i]='0'; }*/
        Print1ToMaxOFDigitsRecursively(number,n,0);
    }

    private static void Print1ToMaxOFDigitsRecursively(char[] number, int n,
            int index) {
        if(index==number.length){
            PrintNumber(number);
            return;
        }
        for(int i=0;i<10;i++){
            number[index]=(char) (i+'0');
            Print1ToMaxOFDigitsRecursively(number,n,index+1);
        }

    }

    private static void PrintNumber(char[] number) {
        boolean isBeginning0=true;
        for(int i=0;i<number.length;i++){
            if(isBeginning0&&number[i]!='0'){
                isBeginning0=false;
            }
            if(!isBeginning0){
                System.out.print(number[i]);
            }
        }
        if(!isBeginning0){//00.000,不需要打印
            System.out.println();
        }

    }
    public static void main(String[] args){
        int n=3;
        Print1ToMaxOFDigits2(n);
    }
}

你可能感兴趣的:(剑指offer之面试题12:打印1到最大的n位数)