其实题目四个关键字就是一个递归的问题,解决:“有多少种方案这种问题”;
递归问题
1、递归改迭代:(递归可以改成迭代,递归是自上而下的倒着想,而迭代是自下而上的一步步更新变量,其实递归和迭代,迭代要更好一点,,因为他所占的空间要少,不需要递归那样用到栈的结构而开出一大片地方来)(但递归具有更强的表达力,用几句代码表达出很复杂的关系,改成迭代则需要写很多才可以)(递归问题分为数值型和非数值型)
楼梯有n阶,小孩一次可以上1\2\3阶,计算小孩有多少种上楼方式 为防止溢出,请将结果mod1000000007
class Test48{
static int mod = 1000000007; //用Int就可以,java int 类型的范围是:-2147483648 到2147483648(10位)
public static void main(String[] args) {
}
static long recursion(int n){
if(n<0) return 0;
if(n==0 || n==1) return 1;
if(n==2) return 2;
return recursion(n-1)%mod+recursion(n-2)%mod+recursion(n-3)%mod;
}
static int recursion2(int n){
if(n<0) return 0;
if(n==0||n==1) return 1;
if(n==2) return 2;
if(n==3) return 4;
int x1 = 1;
int x2 = 2;
int x3 =4;
for(int i=4;i<=n;i++){
int x_1 = x1;
x1 = x2%mod;
x2 = x3%mod;
x3 = ((x1+x2)%mod+x_1)%mod;
}
return x3;
}
}
2、机器人走网格问题:
有一个 x×Y的网格,一个机器人走个点且只能向右或向下,要从左上角到右下角,问机器人有多少种算法,,x+y要小于等于12
关键是 f(x,y) = f(x,y-1)+f(x-1,y)
还是同样有两种写法
class Test48{
public static void main(String[] args) {
}
//倒着想
static int solve(int x,int y){
if(x==1 || y==1){
return 1;
}
return solve(x-1,y)+solve(x,y-1);
}
//顺着想(但是因为是二纬的,所以保存历史数据要用二纬表来保存,但是这个存我觉得很好存哎,因为不用去拿一个变量来回换,而是直接存成二维数组)
static int solve2(int m,int n){
int [][]state = new int[m+1][n+1];//都从第一行或者第一列开始存,不要0的
for(int i=1;i<=n;i++){
state[1][i] = 1;
}
for(int i=1;i<=m;i++){
state[i][1]= 1;
}
for(int i=2;i<=m;i++){
for(int j=2;j<=n;j++){
state[i][j] = state[i][j-1]+state[i][j-1];
}
}
return state[m][n];
}
}
3、硬币表示问题:
8种面值硬币 1,2,5,10,20,50,100,200 给定一个数值n
思路:在循环当中递归,每个小老板只决定最大面额的币用多少张
然后剩下的钱交给下一个去处理
这里比机器人复杂的地方在于不是一个地方要还是不要,,而是这个东西我要一个,或者我要两个,或者我要三个(在循环中递归)
class Test48{
public static void main(String[] args) {
}
static int countways(int n){
if(n<=0) return 0;
return countwayscore(n,new int[]{1,5,10,25},3);//3表示第一次可选范围是0~3
}
static int countwayscore(int n,int[] coins,int cur){
if(cur==0) return 1;
int res =0;
for(int i=0;i*coins[cur]<=n;i++){
int shengyu = n-i*coins[cur];
res+=countwayscore(shengyu,coins,cur-1);
}
return res;
}
}
4、递归问题的非数值问题的解法(就是需要用容器去装了,生成一点,装一点,慢慢改变)
非法括号问题:输入n,打印n对括号的全部有效组合
import java.util.HashSet;
import java.util.Set;
class Test48{
public static void main(String[] args) {
Set<String> par= parenthesis(3);
System.out.println(par);
}
static Set<String> parenthesis(int n){
Set<String> s_n = new HashSet<>();
if(n==1){
s_n.add("()");
return s_n;
}
Set<String> s_n_1 = parenthesis(n-1);
for(String ex:s_n_1){
s_n.add("()"+ex);
s_n.add(ex+"()");
s_n.add("("+ex+")");
}
return s_n;
}
//正着写
static Set<String> parenthesis2(int n){
Set<String> res = new HashSet<>();
res.add("()");
if(n==1){
return res;
}
for(int i=2;i<=n;i++){
Set<String > res_new = new HashSet<>();
for(String e:res){
res_new.add(e+"()");
res_new.add("()"+e);
res_new.add("("+e+")");
}
res = res_new;
}
retu