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

来源:互联网 发布:html如何连接数据库 编辑:程序博客网 时间:2024/06/17 06:34

一、题目

输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,就打印出1、2、3、一起到最大的3位数,即999。

二、思考与分析

这个题目看似简单,但是当输入的n很大时,求最大的n位数用整型或长整型都会溢出。这里需要考虑大数问题。

三、实现

方法一:在字符串上模拟数字加法

用字符串或者数组来表示大数,首先我们把字符串中的每个数字都初始化为’0’,然后每一次为字符串表示的数字加1,再打印出来。因此我们只需要做两件事情:
* 在字符串表达的数字上模拟加法;
* 把字符串表达的数字打印出来;

public class PrintNNum {    public void print(int n) {        if (n <= 0) {            return;        }        char[] arr = new char[n + 1];        for (int i = 0; i < arr.length; i++) {            arr[i] = '0';        }        while (!imcrement(arr)) {            printNum(arr);        }    }    //在字符串表示的数字上加1    private boolean imcrement(char[] arr) {        int len = arr.length - 1;        while (arr[len] == '9') {// 从字符的最右边开始,如果为‘9’就置‘0’,直到不是‘9’就将该位加1            arr[len] = '0';            len--;        }        arr[len] += 1;        if (arr[0] == '1') {            return true;        }        return false;    }    /*     * 按照我们的阅读习惯,将字符串表示的数字打印出来     * 即只有在碰到第一个非0的字符之后才开始打印,直到字符串的结尾     */    private void printNum(char[] arr) {        int isBegin0 = 0;        for (int i = 0; i < arr.length; i++) {            if (arr[i] == '0' && isBegin0 == 0) {                continue;            } else {                isBegin0 = 1;            }            if (isBegin0 == 1) {                System.out.print(arr[i]);            }        }    }}   

注意:

我们在创建数组时,创建了n+1位的数组,当加到最大的n位数时,即99…9时,再加1,就会在第一个字符(下标为0)的位置产生进位,当该位置产生进位时,则表示循环应该结束了。这样也实现了用O(1)时间判断是否已经到了最大的n位数。

方法二:将问题转换成数字排列

我们把问题换个思路考虑,会发现n位所有十进制数其实就是n个从0到9的全排列。也就是说,我们把数字的每一位都 从0到9排列一遍,就可以得到所有的十进制数。只是在打印的时候,排在数字前面的0不打印出来而已。

全排列用递归很容易表达,数字的每一位都可能是0~9中的一个数,然后设置下一位,递归结束的条件是我们已经设置好了数字的最后一位。

//全排列实现打印    private void printToMaxOfNDigits(int n){        if(n <= 0){            return;        }        char[] arr = new char[n];        for (int i = 0; i < 10; i++) {            arr[0] = (char) ('0'+i);            printToMaxOfNDigitsRecursively(arr,n,0);        }    }    private void printToMaxOfNDigitsRecursively(char[] arr, int n, int index) {        if(index == n-1){            printNum(arr);            System.out.print("、");            return;        }        for (int i = 0; i < 10; i++) {            arr[index+1] = (char) (i+'0');            printToMaxOfNDigitsRecursively(arr, n, index+1);        }    }
阅读全文
0 0
原创粉丝点击