7月算法训练------第二十八天(动态规划)解题报告
题目类型:动态规划
题目难度:简单
第一题、53. 最大子数组和
-
题目链接:53. 最大子数组和
-
思路分析:
我们用一个dp数组记录当前位之前(包括当前位)的和,如果当前位与之前位的和小于当前位的值,那么说明这个sum值对当前位的值产生负影响,应不计算之前的sum;当之前位的和比当前位的值大时,说明之前位的和将当前位变大,计入之前位的和。
最终返回dp数组中的最大值就是结果。 -
代码:
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length == 0) return 0;
int[] dp = new int[nums.length];
dp[0] = nums[0];
for(int i = 1; i < nums.length; i++){
if(dp[i-1] + nums[i] < nums[i]){
dp[i] = nums[i];
}else{
dp[i] = dp[i-1] + nums[i];
}
}
Arrays.sort(dp);
return dp[dp.length-1];
}
}
剑指offer
题目类型:动态规划
第二题、剑指 Offer 42. 连续子数组的最大和
- 题目链接:剑指 Offer 42. 连续子数组的最大和
- 思路分析:
这一题和第一题其实是一样的
第三题、剑指 Offer 47. 礼物的最大价值
- 题目链接:剑指 Offer 47. 礼物的最大价值
- 思路分析:
题目要到达矩阵右下角的和最大,我们思考:最后一步的上一步是啥?那当然是grid[m-1][n-1]
的左边一格或者上面的一个能达到最右下角,在这两个数中选出最大的那个,然后加上最后一格的值,就是最大的和。由此推广,矩阵中每一个值的最大值都是左边和上边这两个中最大的那个加上本格的值(除了矩阵第一行和第一列),对于第一行,因为能达到它的方案只有一种,那就是从当前格的右边达到;对于第一列,也只有一种可能,就是从当前格的上面一个到达,所以我们按这个初始化dp数组的第一行和第一列,其余的都是从上或者从左到达中值大的那个再加上当前格的值。 - 代码:
class Solution {
public int maxValue(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
for(int i = 1; i < m; i++){
dp[i][0] = dp[i-1][0] + grid[i][0];
}
for(int j = 1; j < n; j++){
dp[0][j] = dp[0][j-1] + grid[0][j];
}
for(int i = 1; i < m; i++){
for(int j = 1; j < n; j++){
if(dp[i-1][j] < dp[i][j-1]){
dp[i][j] = dp[i][j-1] + grid[i][j];
}else{
dp[i][j] = dp[i-1][j] + grid[i][j];
}
}
}
return dp[m-1][n-1];
}
}