序文
プログラミング言語を学び始めるときは、再帰の学習が不可欠です。再帰は関数がそれ自体を呼び出すプロセスであることは誰もが知っています。再帰的な高度なアプリケーションの問題を見てみましょう。
トピック情報
从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。
输入格式
输入一个整数 n。
输出格式
每行输出一种方案。
同一行内的数必须升序排列,相邻两个数用恰好 1 个空格隔开。
对于没有选任何数的方案,输出空行。
样例1:输入: n=3
输出: 第一行为空,也是答案的一种。
3
2
2 3
1
1 3
1 2
1 2 3
アイデア
最初に例を見てみましょう。与えられた値はn=3です。各数値には、2つのオプションがあるか、オプションがありません。合計結果は8です。上記のように。
あらゆる種類の再帰問題に対して、再帰ツリーを描画できます。各再帰を表すために、ツリーのすべての葉は再帰の結果です。n = 3で再帰ツリーをシミュレートしましょう。しかし、問題が発生しました。リークなしで8つのスキームすべてを記録するにはどうすればよいですか?答えは、n = 3と仮定すると、3つのAピットがあります。最初のピットは1つしか入れられないか、何も入れられません。後の2つについても同じことが言えます。
これには、考えられるすべての結果が含まれます。
オレンジ色のポインターは、現在の位置が配置されているかどうかを表します。
コード
import java.util.Scanner;
public class Main {
static int N=16;
//st数组表示当前这个坑的状态,选或者不选。
static boolean st[]=new boolean[N];
static int n=0;
static void dfs(int u){
//因为从1开始所以u>n的时候才是答案
if(u>n){
for (int i = 1 ; i <=n ; i++) {
//当st[i]=ture的时候意思是选了,这时候输出i的值
if(st[i]==true){
System.out.print (i+" ");
}
}
//打印完了换行
System.out.println ();
//递归结束
return;
}
//下面是两种分支,选,不选、不选是2,选是1,记得递归完了后恢复现场
st[u]=true;
//选了之后递归刀下一个坑
dfs (u+1);
//递归结束后,回溯上到一层,因为上一曾还没有选,所以要把它修改回false。
st[u]=false;
//这是不选的情况
st[u]=false;
//同样也是递归,但他本来就是false,Boolean数组默认就是false,就可以不用写了。
dfs (u+1);
}
public static void main (String[] args) {
Scanner s=new Scanner (System.in);
n=s.nextInt ();
dfs(1);
}
}