前言
在开始学编程语言的时候,就少不了对递归的学习,我们都知道,递归就是函数自己调用自己的过程,下面来看一道递归的进阶应用题。
题目信息
从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。
输入格式
输入一个整数 n。
输出格式
每行输出一种方案。
同一行内的数必须升序排列,相邻两个数用恰好 1 个空格隔开。
对于没有选任何数的方案,输出空行。
样例1:输入: n=3
输出: 第一行为空,也是答案的一种。
3
2
2 3
1
1 3
1 2
1 2 3
思路
先看一下样例,给的值是n=3,对于每一个数都有两种选或者不选的方案。总共的结果就是8种。如上。
对于每一种递归问题,都可以画一个递归树。来表示每一次递归的情况,树的所有叶子就是递归的结果了。下面来模拟一下n=3的递归树,但是这时候问题来了,我要怎么样才能一个不漏的将8种方案全部记录下来呢,答案是顺序排列,假设n=3,那么就有3个坑,- - -,第一个坑只能放1,或者什么都不放,对于后面两个同理。
这样就可以将所有可能的结果包含起来。
橙颜色指针代表的是当前对于这个位置到底放还是不放。
代码
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);
}
}