题目:
输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1,2,3一直到最大的3位数999.
思路:
因为没有指定n的范围,因此直接对数字进行打印,不管是int型还是long型都有可能会溢出。因此我们使用数组来完成。
基于此,有不基于递归的方法1和基于递归的方法2。
方法1中,设置好用于存放数字的数组后,需要设置数组加一,以及进位的方法。
方法2中,直接实现对于每位数字从1到9的打印,需要留意的是当前正在对哪一位数字进行操作,因此每次递归需要一个值进行判断。
两种方法都需要打印函数,该打印函数在第一次遇到除0以外的值时才会开始打印,当开始打印后,后续的0也需要打印。
public class Solution {
//方法一 字符数组
public void dayin(int n){
if (n<=0) {
System.out.println("无效输入!");
return;
}
char[] array = new char[n+1];
for (int i = 0; i <array.length-1 ; i++) {
array[i] = '0';
}
array[n] = '\n';
while (!incrementNumber(array)){
print(array);
}
}
public boolean incrementNumber(char[] array){
int sum =0;
boolean isoverflow = false;//是否溢出
int jinwei = 0; //是否进位
for (int i = array.length-2; i >=0 ; i--) {
sum = array[i]-'0'+jinwei; //初始化sum
if (i==array.length-2){sum++;} //如果是最后一位sum加一
if (sum>=10){ //如果大于10 则需考虑循环完成或进位的情况
if (i==0) isoverflow=true; //表明循环结束,数组加到最大值
else {
jinwei = 1;
array[i] = '0';
}
}
else {
//没有进位 修改array[i]即可,直接跳出循环,进不进位也不重要了,所以不用重置进位值
array[i] = (char) (sum+'0');
break;
}
}
return isoverflow;
}
//打印数字
private static void print(char[] number) {
boolean isBeginning0 = true;
int nLength = number.length;
for (int i = 0; i < nLength; ++i) {
if(isBeginning0 && number[i]!='0'){
isBeginning0 = false;
}
if(!isBeginning0){
System.out.print(number[i]);
}
}
System.out.println();
}
//方法二 递归
//就像我之前想的使用N层循环来实现赋值,但直接for循环没法写的。
// 但通过递归可以实现,主要就是用一个值index,确定在循环的第几层,最后一层进行打印,否则继续循环下去
//打印1到最大的n位数的主方法
public void printToMaxOfDigits(int n){
if (n<=0) {
System.out.println("错误输入");
return;
}
char[] array = new char[n];
for (int i = 0; i <n ; i++) {
array[i] = '0';
}
for (int i = 0; i <10 ; i++) {
array[0] = (char)(i+'0');
printToMaxOfNDigitsRecursively(array,n,0);
}
}
//利用递归实现1到最大的n位数的全排列
public void printToMaxOfNDigitsRecursively(char[] number, int n, int index) {
if (index==n-1){
print(number);
return;
}
for (int i = 0; i <10 ; i++) {
number[index+1] = (char) (i+'0');
printToMaxOfNDigitsRecursively(number,n,index+1);
}
}
}