JZ69 跳台阶 JZ71 跳台阶扩展问题 JZ10 斐波那契数列 JZ70 矩形覆盖

JZ69 跳台阶

描述
一只癞蛤蟆一次可以跳上1级台阶,也可以跳上2级。求该癞蛤蟆跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

分析问题:
1级台阶:一种跳法:1
2级台阶:二种跳法:1+1、2
3级台阶:三种跳法:1+1+1、1+2、2+1
4级台阶:五种跳法:1+1+1+1、1+1+2、1+2+1、2+1+1、2+2

发现规律:当前项跳法等于前两项之和

解法一:递归:

public int jumpFloor(int target) {
   if(target<=2){
       return target;
   }
   return jumpFloor(target-1)+jumpFloor(target-2);
}

解法二:动态规划:

public int jumpFloor(int target) {
    int[] arr = new int[target+1];
    for(int i=1;i<=target;i++){
        if(i<=2){
            arr[i]=i;
        }else{
            arr[i]=arr[i-1]+arr[i-2];
        }
    } 
    return arr[target];
}

动态规划优化:因为只使用到了前两项的值,因此可以借助中间变量来存储前两项的值

public int jumpFloor(int target) {
   int a=1,b=1,c=1;
   for(int i=2;i<=target;i++){
       c=a+b;
       a=b;
       b=c;
   }
   return c;
}

总结:

JZ71 跳台阶扩展问题

描述
一只癞蛤蟆一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该癞蛤蟆跳上一个n级的台阶(n为正整数)总共有多少种跳法。

分析问题:
1级台阶:一种跳法:1
2级台阶:二种跳法:1+1、2
3级台阶:三种跳法:1+1+1、1+2、2+1、3
4级台阶:五种跳法:1+1+1+1、1+1+2、1+2+1、2+1+1、2+2、3+1、1+3、4

发现规律:当前项n的跳法等于前一项的2倍,也就是2[^n-1]

解法一:递归:

public int jumpFloorII(int target) {
   if(target<=1){
       return 1;
   }else{
       return jumpFloorII(target-1)*2;
   }
}

解法二:动态规划:

public int jumpFloorII(int target) {  
  int[] arr = new int[target+1];
  arr[1]=1;
  for(int i=2;i<=target;i++){
      arr[i] = arr[i-1]*2;
  }
  return arr[target];
}

动态规划优化

public int jumpFloorII(int target) {
  int a=1;
  int b=1;
  for(int i=2;i<=target;i++){
      a=b*2;
      b=a;
  }
   return a;
}

解法三:快速幂:

直接优化为求2的n-1次幂

public int jumpFloorII(int target) {
    int a=1;
    for(int i=2;i<=target;i++){
        a*=2;
    }
    return a;
}

优化为求解2的快速幂

public int jumpFloorII(int target) {
   if(target==1){
       return 1;
   }
   return fast(target-1);
}

public int fast(int target) {
    if(target==1){
       return 2;
   }
   int temp = fast(target/2);
   if(target%2==0){
       return temp*temp;
   }else{
       return temp*temp*2;
   }
}

JZ10 斐波那契数列
在这里插入图片描述

解法一:递归:

public int Fibonacci(int n) {
     if(n<=2){
         return 1;
     }else{
         return Fibonacci(n-1)+Fibonacci(n-2);
     }
 }

解法二:动态规划:

public int Fibonacci(int n) {
   int[] arr = new int[n+1];
   for(int i=1;i<=n;i++){
       if(i<=2){
           arr[i]=1;
       }else{
           arr[i]=arr[i-1]+arr[i-2];
       }
   }
   return arr[n];
}

动态规划优化

public int Fibonacci(int n) {
 if(n<=2){
     return 1;
 }
 int a=1,b=1,c=1;
 for(int i=3;i<=n;i++){
     c=a+b;
     a=b;
     b=c;
 }
 return c;
}

JZ70 矩形覆盖

描述
我们可以用 21 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 21 的小矩形无重叠地覆盖一个 2*n 的大矩形,从同一个方向看总共有多少种不同的方法?
注意:约定 n == 0 时,输出 0

分析图解:难点在于找规律,找出所有的情况,不能漏掉。第一次分析时漏掉了2*4的最后一种情形,看题解才发现。当不确定的时候,可以试试N再加一,看看规律是否依旧成立来验证。
在这里插入图片描述解法一:递归:

public int rectCover(int target) {
    if(target<=2){
        return target;
    }
    return rectCover(target-1)+rectCover(target-2);
}

解法二:动态规划:

public int rectCover(int target) {
int[] dp = new int[target + 1];
for (int i = 0; i <= target; i++) {
    if (i <= 2) {
        dp[i] = i;
    } else {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
}
return dp[target];
}

动态规划优化:

public int rectCover(int target) {
  if(target<2){
      return target;
  }
  int a=1,b=1,c=1;
  for(int i=2;i<=target;i++){
      c=a+b;
      a=b;
      b=c;
  }
  return c;
}

总结:此四题都是非常简单的动态规划的入门题。
涉及数据结构:数组
涉及算法:递归、动态规划、快速幂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值