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

来源:互联网 发布:九仙图翅膀进阶数据 编辑:程序博客网 时间:2024/06/04 18:34

解题思路:

这题乍一看看上去还是比较容易,我们很自然的就想到先求出那个最大的n位数,然后在从1开始打印出来即可。这种解法存在一个致命的缺点,当n较大是,所需打印的数有很大部分超过了整形所能表示的范围。在java中,整形用4字节表示,所能表示的整数范围是-2147483648~2147483647。所能表示的数字也顶多是10位,因此当n较大时,我们需要转换思路。既然不能用整形来表示数字,那么可以想到用字符数组来存储数字的每一位。

从整体上来看,需要做两件事:(1)对字符数组代表的数字进行加1操作;(2)对加1后的字符数组进行打印,按照常规方式,需去除前面多余的'0'。具体步骤详见代码注释


/**打印1到最大的n位数 * */public class Solution {public static void print1ToMaxOfDigits(int n) {if (n <= 0) {System.out.println("Invalid Input");}//创建一个具有n个元素的字符数组,并设置初始值都为字符'0'char[] number = new char[n];for (int i = 0; i < number.length ; i++) {number[i] = '0';}while (!incrementIsOverflow(number)) {//如果+1后为越界,则将其打印出来printNumber(number);}}public static boolean incrementIsOverflow(char[] number) {//该标志位用于判断当前字符数组是否达到最大值,如果达到最大值,则停止继续+1的操作boolean isOverFlow = false;//进位符,表示在+1的过程中所产生的进位,开始为0;int nTakeOver = 0;//从字符数组的最后一位开始,进行+1操作,因为+1是在个位发生for (int i = number.length - 1; i >= 0; i--) {//取到当前数组的第i位上的数字字符char digit = number[i];//计算出当前字符所对应的数字加上进位后的结果//当前字符对应的数字用字符-'0'来表示int nSum = digit - '0' + nTakeOver;if (i == number.length - 1) {//如果当前位是数组的末尾,即数字的个位,则数值需要加1nSum++;}//判断当前字符对应的数字是否大于等于10if (nSum >= 10) {//如果当前字符对应的数字大于等于10if (i == 0) {//如果是最高位的数字大于等于10,则超过n位的最大整数isOverFlow = true;} else {//除最高位以外的其他位字符对应的数字大于等于10//产生进位nTakeOver = 1;nSum = nSum - 10;//更新number[i]的数字字符number[i] = (char) (nSum + '0');}} else {//如果当前字符对应的数字小于10,即不会产生进位//只需更新number[i]对应的数字字符number[i] = (char) (nSum + '0');//跳出循环,因为i之前的数字也不可能变,无需循环break;}}return isOverFlow;}/** * 对每次进行+1操作后的数字进行打印,按照常规来打印 * @param number */public static void printNumber(char[] number) {int i;//需要定位到数组中第一个非0的数字for (i = 0; i < number.length ; i++) {if (number[i] != '0') {//如果找到第一个不为0的字符,跳出循环break;}}//从i处开始打印字符数组中的数字while (i < number.length) {System.out.print(number[i]);i++;}//没打印完一个数字,下次从新行开始打印System.out.println();}}


原创粉丝点击