简述:
需要爬N层的楼梯,有max种爬楼梯方式,需要求算总共爬到N层 有几种方法
1. 回溯是比较直观的,就是一层一层向上叠加,走到顶层就是一种方法,得到结果
2. 一维动态规划的话, 就是用一个数组保留走过的楼层,比如最大步伐是3, 然后我现在考虑走到第10层有几种走法
就是 resultArray[10] = resultArray[ 10 - 1] + resultArray[10 - 2] + resultArray[10 - 3] 三者之和
3. 3解法中优化了2中的空间复杂度,用取余的方式实现f(n) = f(n - 1) + f(n - 2) + ... + f(n - k)
例子:
爬4层楼梯 , 则N=4, 有3种步伐,分别为1步,2步,3步
则总共方法7种,一次为
1 + 1 + 1 + 1
1 + 1 + 2
1 + 2 + 1
1 + 3
2 + 1 + 1
2 + 2
3 + 1
算法实现1(回溯法):
使用函数压栈, 不断累加当前楼梯的高度,深度探测是否已经爬到顶了,如果爬到顶了,那么count++,没有那么继续爬,并把步子压到stack中记录步伐顺序
package dynamic_programming;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Stack;
public class ClimbTheFloor {
private static int count = 0;
private static Stack<Integer> stack = new Stack<Integer>();
private static ArrayList<String> resultList = new ArrayList<String>();
public static void main(String[] args) {
InputStream inputStream = System.in;
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferReader = new BufferedReader(inputStreamReader);
//Get limited height
System.out.print("Please Input the Max height: ");
Integer max = null;
try{
max = Integer.parseInt(bufferReader.readLine());
}catch(IOException e){
e.printStackTrace();
}
//Get the max step
System.out.print("Please Input the limited step: ");
Integer limit = null;
try{
limit = Integer.parseInt(bufferReader.readLine());
}catch(IOException e){
e.printStackTrace();
}
Climb(0, max, limit);
System.out.println("There are " + count + " methods !");
for(String record : resultList)
System.out.println(record);
}
public static void Climb(int height, int max, int limit){
if(height == max){
count++;
resultList.add(stack.toString());
}
else{
for(int i = 1;i <= limit; i++)
if(height + i <= max){
stack.push(i);
Climb(height + i, max, limit);
stack.pop();
}
}
}
}
输出:
2) 动态规划实现:
package dynamic_programming;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ClimbTheFloor2 {
public static void main(String[] args) {
InputStream inputStream = System.in;
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferReader = new BufferedReader(inputStreamReader);
//Get limited height
System.out.print("Please Input the Max height: ");
Integer max = null;
try{
max = Integer.parseInt(bufferReader.readLine());
}catch(IOException e){
e.printStackTrace();
}
//Get the max step
System.out.print("Please Input the limited step: ");
Integer limit = null;
try{
limit = Integer.parseInt(bufferReader.readLine());
}catch(IOException e){
e.printStackTrace();
}
System.out.println("Number of Methods: " + CountMethods(max, limit));
}
/*
* @ Height : the height of the destination
* @ max : the max number of steps you can climb upstairs once
*/
private static int CountMethods(int max, int limit){
int resultArray[] = new int[max + 1];
resultArray[0] = 1;
for(int i = 1;i <= max;i++){
int sum = 0;
for(int j = 1;j <= limit;j++){
if(i - j < 0)
break;
else{
sum += resultArray[i - j];
}
}
resultArray[i] = sum;
}
return resultArray[max];
}
}
输出:
3) 优化了2)中的空间复杂度, 将空间降到了O(k) , 其中k为可以走的步数的种类
package dynamic_programming;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ClimbTheFloor3 {
public static void main(String[] args) {
InputStream inputStream = System.in;
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
Integer limit = null;
try{
System.out.print("Please Input Limited step:");
limit = Integer.parseInt(bufferedReader.readLine());
}catch(IOException e){
e.printStackTrace();
}
Integer max = null;
try{
System.out.print("\nPlease Input Max Height: ");
max = Integer.parseInt(bufferedReader.readLine());
}catch(IOException e){
e.printStackTrace();
}
ClimbTheFloor3 obj = new ClimbTheFloor3();
System.out.print("\nMethods: " + obj.CountMethods(max, limit));
}
private int CountMethods(int max, int limit){
if(max < 0 || limit < 0)
throw new IllegalArgumentException("Wrong arguments! ");
int step[] = new int[limit];
for(int i = 0; i < limit; i++)
step[i] = 1;
for(int i = 1; i <= max; i++){
int sum = 0;
for(int j = 0; j < limit; j++){
if(i - (j + 1) == 0){
sum++;
break;
}
sum += step[(i - (j + 1)) % limit];
}
step[(i - 1) % limit] = sum;
}
return step[(max - 1) % limit];
}
}
输出: