动态规划练习

:                   


题目一:

53. 最大子数组和

难度中等5678收藏分享切换为英文接收动态反馈

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

解法一:动态规划

class Solution {
  public int maxSubArray(int[] nums) {
		int[] dp = new int[nums.length];
		dp[0] = nums[0];
		int max = nums[0];
		for (int i = 1; i < nums.length; i++) {
			dp[i] = Math.max(dp[i- 1] + nums[i], nums[i]);	
			if (max < dp[i]) {
				max = dp[i];
			}
		}
		return max;
	}
}

解法二:

class Solution {
    public int maxSubArray(int[] nums) {
        int pre = 0, maxAns = nums[0];
        for (int x : nums) {
            pre = Math.max(pre + x, x);//若当前指针元素之前的和小于0 ,则丢弃当前元素之前的数列
            maxAns = Math.max(maxAns, pre);//再将当前值与最大值进行比较
        }
        return maxAns;
    }
}

题目2:

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:2
示例 2:

class Solution {

    int mm =1000000007;
    public int numWays(int n) {

   int ff [] = new int[19900];
  
    ff[1]=1;
    ff[0]=1;//注意可以从0个台阶跳跃
        for (int i = 2; i <= n; i++) {
          ff[i]=(ff[i-1]+ff[i-2])%mm;//可以跳跃一个也可以跳跃两个
        }
        return ff[n];
    }
}


题目3:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

class Solution {
    public int climbStairs(int n) {
     int [] ff= new int[1999999];
     ff[0]=1;
     ff[1]=1;
     for(int i = 2;i<=n;i++){
         ff[i]= ff[i-1]+ff[i-2];
     }

     return ff[n];
     }
}

题目4:

剑指 Offer II 088. 爬楼梯的最少成本

难度简单62

数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。

每当爬上一个阶梯都要花费对应的体力值,一旦支付了相应的体力值,就可以选择向上爬一个阶梯或者爬两个阶梯。

请找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。

示例 1:

输入:cost = [10, 15, 20]
输出:15
解释:最低花费是从 cost[1] 开始,然后走两步即可到阶梯顶,一共花费 15 。

 示例 2:

输入:cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
输出:6
解释:最低花费方式是从 cost[0] 开始,逐个经过那些 1 ,跳过 cost[3] ,一共花费 6 。

提示:

  • 2 <= cost.length <= 1000
  • 0 <= cost[i] <= 999

解法一:

求解思路
动态规划求解:

每次跳跃只有两种可能,跳跃一个阶梯或者两个阶梯
当前i 所需要的花费 = min( 跳到i-1最小花费 + 从i-1 跳到i 的花费,跳到i-2最小花费 + 从i-2 跳到i 的花费) => dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
边界条件 dp[0] = dp[1] = 0


class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int[] dp = new int[n + 1];
        dp[0] = dp[1] = 0;
        for (int i = 2; i <= n; i++) {
//每个台阶对应相应的体力
            dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[n];
    }
}


 

解法二

   class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int prev = 0, curr = 0;//当前值和下一个值
        for (int i = 2; i <= n; i++) {
    //在当前最大值加上下一个值中找最大的
            int next = Math.min(curr + cost[i - 1], prev + cost[i - 2]);
            prev = curr;
            curr = next;
        }
        return curr;
    }
}


题目5:198. 打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 1:

输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:

输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。
 

class Solution {
    public int rob(int[] nums) {
     int n = nums.length;
     int dp [] = new int[n];
     dp[0] = nums[0];
     int ans= dp[0];//如果是一个元素,那么直接给ans,因为他进不了循环;
     for( int i=1 ;i<n ;i++){
      if(i==1){
          dp[1] =Math.max(dp[0],nums[1]);
      }else dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i]);
      ans=Math.max(ans,dp[i]);
     }
     return ans;
    }
}

第6题

1137. 第 N 个泰波那契数

难度简单240

泰波那契序列 Tn 定义如下: 

T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2

给你整数 n,请返回第 n 个泰波那契数 Tn 的值。

示例 1:

输入:n = 4
输出:4
解释:
T_3 = 0 + 1 + 1 = 2
T_4 = 1 + 1 + 2 = 4

示例 2:

输入:n = 25
输出:1389537

提示:

  • 0 <= n <= 37
  • 答案保证是一个 32 位整数,即 answer <= 2^31 - 1
class Solution {
    public int tribonacci(int n) {
    if(n==1||n==0) return n ; 
    //prve 上上个数
    //prve1 上个数
    //cur 现在的数
     //cur = prve +prve1 + cur;
    int prve =0 ,prve1= 1 ,cur=1;  
    for(int i = 3;i<=n;i++){
        int tem = cur;
        cur= prve+prve1 +cur;
        prve=prve1;
        prve1= tem;
    }
    return cur;
    }
}

解法二:

class Solution {
    public int tribonacci(int n) {
     int []  a = new int[38];
    a[0]=0;a[1]=1;a[2]=1;
    for(int i =3; i<=n;i++){
        a[i]=a[i-1]+a[i-2]+a[i-3];
       
    }
       return a[n];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值