Java 递归爬梯算法
我正在尝试将以下算法从递归更改为迭代,但在这样做时遇到了问题。(书:《破解编码面试》) 问题:“一个孩子跑上n步楼梯,一次可以跳1步、2步或3步。实现一个方法来计算孩子可以跑上楼梯的方式。” 书中的答案(递归):Java 递归爬梯算法,java,algorithm,debugging,recursion,iteration,Java,Algorithm,Debugging,Recursion,Iteration,我正在尝试将以下算法从递归更改为迭代,但在这样做时遇到了问题。(书:《破解编码面试》) 问题:“一个孩子跑上n步楼梯,一次可以跳1步、2步或3步。实现一个方法来计算孩子可以跑上楼梯的方式。” 书中的答案(递归): 公共静态int countWays(int n,int[]映射){ if(n-1) 返回映射[n]; map[n]=countWays(n-1,map)+countWays(n-2,map)+countWays(n-3,map); 返回映射[n]; } 我的答复(反复): 公共静态i
公共静态int countWays(int n,int[]映射){
if(n<0)
返回0;
如果(n==0)
返回1;
如果(映射[n]>-1)
返回映射[n];
map[n]=countWays(n-1,map)+countWays(n-2,map)+countWays(n-3,map);
返回映射[n];
}
我的答复(反复):
公共静态int countWays(int n,int[]映射){
对于(int i=1;i硬编码第一个索引,使其值为1,然后将总和的每个项放入其自己的if语句中,以检查负索引。如果索引为负,则不将其包含在总和中
或者,您可以只硬编码前三个值,然后从4开始,不必担心它。硬编码第一个索引的值为1,然后将总和的每个项放入其自己的if语句中,以检查是否有负索引。如果索引为负,则不要将其包含在总和中
或者,您可以只硬编码前三个值,然后从4开始,不必担心它。因为这显然是一个编码面试问题……我将向您展示一个类似的解决方案,供您回顾,在Scala
中,以帮助您学习基础知识
import scala.annotation.tailrec
object Main {
/**
* Count ways to make change...
*/
def countChange(money: Int, coins: List[Int]): Int = {
def reduce(money: Int, coins: List[Int]): Int ={
if (money == 0) 1
else if (money < 0 || coins.isEmpty) 0
else reduce(money - coins.head, coins) + reduce(money, coins.tail)
}
reduce(money, coins)
}
}
import scala.annotation.tailrec
对象主体{
/**
*数一数改变的方法。。。
*/
def countChange(货币:整数,硬币:列表[Int]):整数={
def reduce(money:Int,coins:List[Int]):Int={
如果(货币==0)1
否则如果(货币<0 | |硬币。i空)0
否则减少(货币-硬币。头部,硬币)+减少(货币,硬币。尾部)
}
减少(金钱、硬币)
}
}
因为这显然是一个编码面试问题……我将向您展示一个类似的解决方案,让您在Scala中查看,,以帮助您学习基础知识
import scala.annotation.tailrec
object Main {
/**
* Count ways to make change...
*/
def countChange(money: Int, coins: List[Int]): Int = {
def reduce(money: Int, coins: List[Int]): Int ={
if (money == 0) 1
else if (money < 0 || coins.isEmpty) 0
else reduce(money - coins.head, coins) + reduce(money, coins.tail)
}
reduce(money, coins)
}
}
import scala.annotation.tailrec
对象主体{
/**
*数一数改变的方法。。。
*/
def countChange(货币:整数,硬币:列表[Int]):整数={
def reduce(money:Int,coins:List[Int]):Int={
如果(货币==0)1
否则如果(货币<0 | |硬币。i空)0
否则减少(货币-硬币。头部,硬币)+减少(货币,硬币。尾部)
}
减少(金钱、硬币)
}
}
公共静态int countWays(int n,int[]映射){
如果(n==0 | | n==1)
返回1;
如果(n==2)
返回2;
map[0]=1;
map[1]=1;
map[2]=2;
对于(int i=3;i公共静态int countWays(int n,int[]map){
如果(n==0 | | n==1)
返回1;
如果(n==2)
返回2;
map[0]=1;
map[1]=1;
map[2]=2;
对于(int i=3;i您使用的迭代方法称为自底向上动态规划。它不同于带记忆的自顶向下递归。自底向上更有效,因为您避免了与递归相关的堆栈开销
Steps:
1 -> 1 = 1 way
2 -> 11, 2 = 2 ways
3 -> 111, 12, 21, 3 = 4 ways
4 -> 1111, 112, 121, 211, 22, 31, 31 = 7 ways
另一种解决索引问题的方法是创建一个最小大小为3的数组,并从第三个索引开始。这会占用更多的空间,但会简化代码
public int countWaysDP(int n) {
if (n < 0) {
throw new IllegalArgumentException();
}
int[] dp = new int[Math.max(3, n)];
dp[0] = 1; // 1
dp[1] = 2; // 11, 2
dp[2] = 4; // 111, 12, 21, 3
for (int i = 3; i < n; i++) {
dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
return dp[n - 1];
}
public int countWaysDP(int n){
if(n<0){
抛出新的IllegalArgumentException();
}
int[]dp=新的int[Math.max(3,n)];
dp[0]=1;//1
dp[1]=2;//11,2
dp[2]=4;//111,12,21,3
对于(int i=3;i
希望这对您的培训有所帮助。您使用的迭代方法称为自底向上动态编程。它不同于带记忆的自顶向下递归。自底向上更有效,因为您避免了与递归相关的堆栈开销
Steps:
1 -> 1 = 1 way
2 -> 11, 2 = 2 ways
3 -> 111, 12, 21, 3 = 4 ways
4 -> 1111, 112, 121, 211, 22, 31, 31 = 7 ways
另一种解决索引问题的方法是创建一个最小大小为3的数组,并从第三个索引开始。这会占用更多的空间,但会简化代码
public int countWaysDP(int n) {
if (n < 0) {
throw new IllegalArgumentException();
}
int[] dp = new int[Math.max(3, n)];
dp[0] = 1; // 1
dp[1] = 2; // 11, 2
dp[2] = 4; // 111, 12, 21, 3
for (int i = 3; i < n; i++) {
dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
return dp[n - 1];
}
public int countWaysDP(int n){
if(n<0){
抛出新的IllegalArgumentException();
}
int[]dp=新的int[Math.max(3,n)];
dp[0]=1;//1
dp[1]=2;//11,2
dp[2]=4;//111,12,21,3
对于(int i=3;i
希望这对您的培训有所帮助。有关Python中的迭代O(n)和O(log(n))解决方案,请参阅。有关Python中的迭代O(n)和O(log(n))解决方案,请参阅。