九十四.深入递归(一)

题一:走楼梯
有个小孩正上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶、3阶。
请实现一个方法,计算小孩有多少种上楼的方式
为了防止溢出,请将结果Mod 1000000007
给定一个正整数int n ,请返回一个数,代表上楼的方式数。
保证n小于等于100000。

解法一:

import java.util.Scanner;

public class lianXi {

	static final int mod = 1000000007;
	public static int solve1(int n){
		if(n<0)
			return 0;
		if(n==0||n==1)
			return 1;
		if(n==2)
			return 2;
		return solve1(n-1)%mod + solve1(n-2)%mod + solve1(n-3)%mod;
	}
	
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int res = solve1(n);
		System.out.println(res);
	}
}

解法二:

import java.util.Scanner;

public class lianXi {

	static final int mod = 1000000007;
	public static int solve2(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;
	}
	
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int res = solve2(n);
		System.out.println(res);
	}
}

在这里插入图片描述

题二:机器人走方格
有一个x * y 的网络,一个机器人只能走格点且只能向右或向下走,要从左上角走到右下角。
请设计一个算法,计算机器人有多少种走法。
给定两个正整数int x, int y, 请返回机器人的走法数目。保证x + y小于等于12

解法一:

import java.util.Scanner;

public class lianXi {

	public static int solve1(int x, int y){
		if(x==1 || y==1)
			return 1;
		return solve1(x-1, y) + solve1(x,y-1);
	}
	
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int x = in.nextInt();
		int y = in.nextInt();
		int res = solve1(x,y);
		System.out.println(res);
	}
}

解法二:

import java.util.Scanner;

public class lianXi {

	public static int solve1(int x, int y){
		int[][] state = new int[x+1][y+1];
		for(int i = 1; i<=x; i++){
			state[i][1] = 1;
		}
		
		for(int j = 1; j<=y; j++){
			state[1][j] = 1;
		}
		
		for(int i = 2; i<=x; i++){
			for(int j = 2; j<=y; j++){
				state[i][j] = state[i][j-1] + state[i-1][j];
			}
		}
		return state[x][y];
	}
	
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int x = in.nextInt();
		int y = in.nextInt();
		int res = solve1(x,y);
		System.out.println(res);
	}
}

在这里插入图片描述
题三:硬币表示某个给定数值
假设我们有4种不同面值的硬币{1,2,5,10,20,50,100,200} ,用这些硬币组合构成一个给定的数值n。
问总共有多少种可能的组合方式?

import java.util.Scanner;

public class lianXi {

	public static int countWays(int n){
		if(n <= 0)
			return 0;
		return countWaysCore(n, new int[]{1,5,10,25}, 3);
	}
	
	public 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;
	}
	
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		for(int i = 1; i<n; i++){
			int ways = countWays(i);
			System.out.println(i + "---" + ways);
		}
	}
}

在这里插入图片描述
题四:“逐步生成结果”之非数值问题
实现一种算法,打印n对括号的全部有效组合(即左右括号正确配对)。
示例
输入:3
输出:((())),(()()),(())(),()(()),()()()

import java.util.HashSet;
import java.util.Set;

public class lianXi {

	public 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 e : s_n_1){
			s_n.add("()" + e);
			s_n.add(e + "()");
			s_n.add("(" + e + ")");
		}
		return s_n;
	}
	
	public static void main(String[] args){
		Set<String> parenthesis = parenthesis(3);
		System.out.println(parenthesis);
	}
}

在这里插入图片描述

题五:字符串集合的全排列

import java.util.ArrayList;

public class lianXi {

	public static ArrayList<String> getPermutation0(String A){
		int n = A.length();
		ArrayList<String> res = new ArrayList<>();
		res.add(A.charAt(0) + "");  //初始化包含第一个字符
		
		for(int i = 1; i < n; i++){//第二个字符插入到前面生成集合的每个元素里面
			ArrayList<String> res_new = new ArrayList<>();
			char c = A.charAt(i); //新字符
			for(String str : res){  //访问上一趟集合中的每个字符串
				//插入到每个位置,形成一个新串
				String newStr = c + str; //加在前面
				res_new.add(newStr);
			    newStr = str + c; //加在后面
			    res_new.add(newStr);
			    //加在中间
			    for(int j = 1; j < str.length(); j++){
			    	newStr = str.substring(0,j) + c + str.substring(j);
			    	res_new.add(newStr);
			    }
			}
			res = res_new; //更新
		}
		return res;
	}
	
	public static void main(String[] args){
		ArrayList<String> res = getPermutation0("abcd");
		System.out.println(res.size());
		System.out.println(res);
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值