想了好久,看代码反应不过来,还是用代码debug一下,终于明白了 算法的回溯是怎么回事了
代码暂时参考 https://www.cnblogs.com/rolly-yan/p/3892123.html
这个在打印 时做的判断,jianzhioffer 上是加了 字符'0'在打印的时候 加以区分,
数据结构的思想:
设置char[] number 的字符数组的结构,长度为 N位,并没有把所有的数存下来,而是 打印一个,覆盖一个的形式。也就是说,任何时候,看到的 num里面表现出的信息是 0~N位最大数之间 某一个数的信息。
num[0]存储的是 最高位的信息,依次,直到最低位个位用num[N-1]存储。
重要的是回溯递归的过程,很重要,比如N=2;
最开始 num[0] index =0 固定了最高位, 是循环 i 在0 位置,然后带入PrintMaxOfNdigits函数index=0,判断不满足,进入for循环,这时候的for循环要管理的是 num[1] (高一位被锁定了)也就是N位数的次高位的信息了。
所以次高位 i=0 开始index=1,下个语句又进入PrintMaxOfNdigits函数,注意此时进入的index = 2,满足if语句,于是执行打印函数,print函数有一个判断,后面在单独说这个函数。 然后按打印函数规则打出num,这个num为000,没有输出;;此时return 函数。
那么这里的return 是返回到哪里了呢?就是上一个for循环中,那时候的 index=1,i=0,那么现在 index =1,i=1,了
然后又可以进入if 还满足,这次打印出 1; 继续回到上个循环 index=1,现在 index+1 ==2了,num存储的是 num[0]=0,num[1]=0,num[2]=i=2, 打印出2;。。。。。。
如果到打印出9了(这里输出的都是1,,,,9),之后呢,这个时候发现循环判断条件 i<10不满足了,那么本PrintMaxOfNdigits 执行到了最后。接下来要到哪里呢? 就是返回这个循环的上个循环,也就是index=0,i=0的循环(也就是当前刚刚结束的),那么现在i=1,再次开启循环,循环又嵌套循环 index=1,i=0~9 满足if条件,然后输出(这里输出的是 10,11,12,13,。。,19)。i=10不满足小循环返回到 index=0,i=2的那里去。。。。。。依次 N=n是一样的循环思路。
这里说下Print函数,很重要,加了个flag ,因为要把number[0~N-1]都读出来然后输出,输出的判断条件是num[ i ]不为0的最高位开始读,而且之后的位都要输出。这样避免了 比如N=3 num[0]=0,num[1]=0,num[2]=3,也就是3的情况错输成003;
为什么要加flag呢?flag这里是标志 要真正输出值的最高位的,到在这位时候 flag被设为可行值,那么之后的低位的判断flag均可,也就是要被输出,否则 (不加flag)比如N=3 num[0]=0,num[1]=5,num[2]=0,就会输出5 而不是 50 了。这是一个跟跳出多重循环很类似的是一种技巧。
package test;
//import java.math.BigInteger;
public class print1toNb {
public static void main(String[] args) {
// TODO Auto-generated method stub
new print1toNb().Test1(3);
}
public void PrintMaxOfNdigits(int[] number,int length,int index){
if(index ==length-1){
PrintNumber(number);
return;
}
for(int i=0;i<10;i++){
number[index+1]=i;
PrintMaxOfNdigits(number, length, index+1);
}
}
public void Test1(int n){
if(n<=0)
return;
int[] number = new int[n];
for(int i=0;i<10;i++){
number[0]=i;
PrintMaxOfNdigits(number, n, 0);
}
}
public void PrintNumber(int[] number){ //该方法是负责打印一个正类,千万不要尝试将数组变成一个整数
boolean isBeginning=true;
for(int i=0;i