[leetCode]剑指 Offer 17. 打印从1到最大的n位数
解法一
这题需要考虑大数问题,因为int类型能表示的数字是有范围的。当n很大时会发生溢出。需要使用字符串模拟数字加法求解。
// "static void main" must be defined in a public class.
public class Main {
public static void main(String[] args) {
printOne2MaxOfNDigits(2);
}
public static void printOne2MaxOfNDigits(int n){
if(n < 0) return;
char[] number = new char[n];
//这里要进行初始化,char[]初始值不确定
Arrays.fill(number,'0');
while(!incrememnt(number)){
printNumber(number);
// System.out.print(Arrays.toString(number));
}
}
private static boolean incrememnt(char[] number){
boolean isOverflow = false;//溢出标志位
int takeOver = 0;//进位
int len = number.length;
for(int i = len - 1; i >= 0; i--){
//把字符转化位0~9之间的数字并加上进位
int nSum = number[i] - '0' + takeOver;
if(i == len - 1)
++nSum;
if(nSum >= 10){
if(i == 0){
isOverflow = true;
}else{
nSum -= 10;
number[i] = (char)(nSum + '0');//需要强转
takeOver = 1;
}
}else{
number[i] = (char)('0' + nSum);//需要强转
break;
}
}
return isOverflow;
}
private static void printNumber(char[] number){
boolean isBeginning0 = true;
int len = number.length;
for(int i = 0; i < len; i++){
if(isBeginning0 && number[i] != '0')
isBeginning0 = false;
if(!isBeginning0){
System.out.print(new String(number, i,len - i)+" ");
break;
}
}
}
}
解法二 全排列
第二种方法使用全排列,如上图所示。一个n位数每一位都有0~9种取法,我们可以先确定高位再递归确定低位,最后打印输出
// "static void main" must be defined in a public class.
public class Main {
public static void main(String[] args) {
printOne2MaxOfNDigits(2);
}
//全排列解法
public static void printOne2MaxOfNDigits(int n){
if(n < 0) return;
char[] number = new char[n];
//这里要进行初始化,char[]初始值不确定
Arrays.fill(number,'0');
//每一位都有0~9种取法
for(int i = 0; i < 10; i++){
//先固定高位
number[0] = (char)( i + '0');
printOneToMaxOfNRecurvely(number,0);
}
}
private static void printOneToMaxOfNRecurvely(char[] number, int index){
//递归到了最低位
if(index == number.length - 1){
printNumber(number);
return;
}
//逐一递归确定低位,每一位有0~9种选择
for(int i = 0; i < 10; i++){
number[index+1] = (char)('0' + i);
//向低位递归
printOneToMaxOfNRecurvely(number,index+1);
}
}
private static void printNumber(char[] number){
boolean isBeginning0 = true;
int len = number.length;
for(int i = 0; i < len; i++){
if(isBeginning0 && number[i] != '0')
isBeginning0 = false;
if(!isBeginning0){
System.out.print(new String(number, i,len - i)+" ");
break;
}
}
}
}