爬楼梯问题

简述:

需要爬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];
	}
}


输出:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值