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

每天两道的目标已经被鸽了好几天了...我太难了


package cn.zxy.interview;

import org.junit.Test;

import java.util.Arrays;

/**
 * 面试题17: 打印从1到最大的n位数
 * 
 * 方法1: 关键点: 进位  溢出  
 * 方法2: 递归
 */


public class A17_PrintOneToMaxOfNDigits {

@Test
    public void main(){
        printOneToMax(3);
    }

    public void printOneToMax(int n){
        if(n <= 0) return;

        //1.字符数组保存要打印的数
        char[] number = new char[n];
        //2.初始化数组元素为'0'
        Arrays.fill(number, '0');

        while(!numberIncrement(number)){
            printNumber(number);
        }

    }

    /**
     * 打印方法
     * @param number
     */
    private void printNumber(char[] number) {
        //遇到第一个非零数字后 将flag置为true
        //打印时先检查flag  只有是true才启动打印
        boolean flag = false;

        for (int i = 0; i < number.length; i++) {
            if(!flag && number[i] != '0'){
                flag = true;
            }

            if(flag){
                System.out.print(number[i]);
            }
        }
        System.out.println();
    }

    private boolean numberIncrement(char[] number) {
        //1.溢出标志位
        boolean isOverflow = false;
        //2.需要往高位进位的数
        int carryNum = 0;
        //3.记录每次加和操作的临时变量
        int sumTemp = 0;

        //4.for循环从数组最后一位处理, 相当于在个位数进行加一
        for (int i = number.length-1; i >= 0; i--) {
            ///对每一位取出-->与进位数相加
            sumTemp = number[i] - '0' + carryNum;

            if(i == number.length-1) sumTemp++;

            //首位溢出则结束 其他位溢出进位
            if(sumTemp >= 10){
                if(i == 0){
                    isOverflow = true;
                }else{
                    sumTemp -= 10;
                    carryNum = 1;
                    number[i] = (char)(sumTemp + '0');
                }
            }else{
                number[i] = (char)(sumTemp + '0');
                return isOverflow;
            }
        }
        return isOverflow;
    }


    // 递归方法
    /*
    用递归的方法设置每一位, 第一次递归到最深, 然后从最深处加1, 最深一层循环完后, 回退一层, 次深层加一后, 再进入最深一层
    结束条件: 递归深度为数字位数+1
    
    注意这里递归深度的边界容易容错 因为我们是在边界条件中打印, 因此到达边界时, 三位数已经设置好了, 也就是说, 这时候index应该自增长为3了
    而index=3已经是尽头, 不会再进行for循环, 而是直接返回到index=2, 进行个位的自增
    增长完后进入边界, 打印, 返回, 以此类推...
    
     */
    @Test
   public void recMain(){
        int N = 3;
        char[] number = new char[N];
        //初始化为0
        Arrays.fill(number, '0');
        printOneToMaxRec(number, 0);
    }

   public void printOneToMaxRec(char[] number, int index){
       //System.out.println(index + "层开始...");
        if(index == number.length) {
            printNumber(number);
            return;
        }

        for(int i = 0; i < 10; i++){
            number[index] = (char)(i + '0');
            printOneToMaxRec(number, index+1);
        }
    }

}

你可能感兴趣的:(面试题17: 打印从1到最大的n位数)