美文网首页
面试题17:打印1到最大的N位数

面试题17:打印1到最大的N位数

作者: 繁星追逐 | 来源:发表于2019-08-24 18:52 被阅读0次
  • 输入数字n,按顺序打印处1到最大的n位十进制数,比如输入3,则打印1~999之间的数

思路一:如果直接按照数字循环输出的话,可能会遇到大数问题。
代码如下:

/**
     * 边界
     * 这种情况可能存在大数问题,通过字符串去解决大数问题
     * @param n
     */
    public static void printFrom1ToMaxOfNDigit(int n) {
        if (n <=0){
            return;
        }
        int max = (int) Math.pow(10,n)-1;
        for (int i=1;i <= max;i++){
            System.out.println(i);
        }

    }

思路二:使用数组模拟以避免大数问题
创建一个大小为n的数组,while给每次num数组形成的值加1,如果溢出则不再继续加1,每次输出加1后从不为0的数开始的值。
加1操作的实现在于,for循环从最后一位开始,给数组每次调用都会加1,如果没有产生进位,则直接将相应位置的数字加1并终止循环,返回false;如果产生进位(即记录的上个累加和大于等于10,因为number[i]不能大于9,所以通过记录累加和的方式,判断是否需要进位)分为两种情况,第一种是进位到第一位直接返回true,如果只是累加和大于等于10,则将累加和归0,数组当前位归0。
打印操作用for循环可以设置一个标志位,只有当前数组中的数值不为0时,改动标志位才正式开始打印。同时因为多次调用,执行完毕后输出换行。
代码如下:

/**
     *用数组表示大数
     * @param n
     */
    public static void printFrom1ToMaxOfNDigit_1(int n) {
        if (n <=0){
            return;
        }
        int[] number = new int[n];
        while(!increment(number,n)){
            printNumber(number);
        }

    }

    private static void printNumber(int[] number) {
        int len = number.length;
        boolean isStart = false;
        for (int i=0;i<len;i++){
            if (!isStart && number[i] != 0){
                isStart = true;
            }
            if (isStart){
                System.out.print(number[i]);
            }

        }
        System.out.println();
    }

    private static boolean increment(int[] number, int n) {
        boolean isOverflow = false;
        int nTakeOver = 1;
        for (int i=n-1;i>=0;i--){
            //因为number[i]不能大于9,所以通过记录累加和的方式,判断是否需要进位
            int sum = number[i] + nTakeOver;
//            if (i == n-1){
//                sum++;
//            }
            //超过10
            if (sum >= 10){
                 if (i == 0){
                     isOverflow = true;
                 }else{
                     sum-=10;
                     number[i] = sum;
                 }
            }else {
                number[i]++;
                break;
            }
        }

        return isOverflow;
    }


/**
     *用字符串表示大数
     * @param n
     */
    public static void printFrom1ToMaxOfNDigit_2(int n) {
        if (n <=0){
            return;
        }
        StringBuilder sb = new StringBuilder();
        for (int i=0;i<n;i++){
            sb.append('0');
        }
        while(!increment1(sb,n)){
            printNumber1(sb);
        }

    }

    private static void printNumber1(StringBuilder sb) {
        boolean isStart = false;
        for (int i=0;i<sb.length();i++){
            if (sb.charAt(i) != '0' && !isStart){
                isStart = true;
            }
            if (isStart){
                System.out.print(sb.charAt(i));
            }
        }
        System.out.println();
    }

    private static boolean increment1(StringBuilder sb, int n) {
        boolean isOverFlow = false;
        int Take = 1;
        for (int i=n-1;i>=0;i--){
            //将字符-'0'转换为字符串,再转换为整数
            int sum = sb.charAt(i)-'0' + Take;
            if (sum >= 10){
                if (i==0){
                    isOverFlow = true;
                }else {
                    sum-=10;
                    sb.setCharAt(i,'0');
                }
            }else {
                //将整数转换为字符串,在转换为字符
                sb.setCharAt(i, (char)(sum+'0'));
                break;
            }
        }
        return isOverFlow;
    }

思路三:
由于数字的每一位都由0到9构成,所以从第一位开始将每一位依次设置为0-9之中的一位,因为每一位以及以后每一位设置都是一样的,所以采用递归,递归索引从0开始递归,传入一个数组,如果索引的值为数组的长度,则打印数组,跳出方法,否则依次给该索引位置设置0到9不同的值,并递归调用到下一位索引位置。
代码如下:

public static void printFrom1ToMaxOfNDigit_3(int n){
        if (n<=0){
            return;
        }
        int[] number = new int[n];
        //递归计算从-1开始,因为递归过程是从index+1正式开始
        printFrom1ToMaxOfNDigitRecursive(number,n,0);
    }

    private static void printFrom1ToMaxOfNDigitRecursive(int[] number, int length, int index) {
        //终止条件到最后一位
        if (index == length){
            printNumber(number);
            return;
        }
        for (int i=0;i<10;i++){
            number[index] = i;
            printFrom1ToMaxOfNDigitRecursive(number,length,index+1);
        }
    }

相关文章

网友评论

      本文标题:面试题17:打印1到最大的N位数

      本文链接:https://www.haomeiwen.com/subject/limqectx.html