0
点赞
收藏
分享

微信扫一扫

LeetCode 剑指 Offer II 动态规划(四) 专题总结

at小涛 2022-03-11 阅读 66

往期文章 :

  • LeetCode 剑指 Offer II 回溯(上) 专题总结
  • LeetCode 剑指 Offer II 回溯(下) 专题总结
  • LeetCode 剑指 Offer II 动态规划(一) 专题总结
  • LeetCode 剑指 Offer II 动态规划(二) 专题总结
  • LeetCode 剑指 Offer II 动态规划(三) 专题总结

目录

在这里插入图片描述
后两道都是0-1背包问题

100. 三角形中最小路径之和

题目:

给定一个三角形 triangle ,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。

示例:

输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
2
3 4
6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

提示:

  • 1 <= triangle.length <= 200
  • triangle[0].length == 1
  • triangle[i].length == triangle[i - 1].length + 1
  • -104 <= triangle[i][j] <= 104

思路:

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int n = triangle.size();
        int m = n; // 最底层列数
        vector<int> dp(m, 0);
        for(int i = 0; i < n; i++) {
            for(int j = i; j >= 0; j--) {
                if(j == 0) {
                    dp[0] += triangle[i][j];
                    continue;
                }
                if(j == i) {
                    dp[j] = dp[j-1] + triangle[i][j];
                    continue;
                }
                dp[j] = min(dp[j-1], dp[j]) + triangle[i][j];
            }
        }
        return *min_element(dp.begin(), dp.end());
    }
};

101. 分割等和子集

题目:

给定一个非空的正整数数组 nums ,请判断能否将这些数字分成元素和相等的两部分。

示例:

输入:nums = [1,5,11,5]
输出:true
解释:nums 可以分割成 [1, 5, 5] 和 [11] 。

提示:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 100

思路:

二维数组

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n = nums.size();
        int sum = 0, maxNum = 0;
        for(auto& num : nums) {
            sum += num;
            maxNum = max(maxNum, num);
        }
        int target = sum / 2;
        if(sum & 1 || target < maxNum) {
            return false;
        }
        vector<vector<bool>> dp(n, vector<bool>(target+1, false));
        for(int i = 0; i < n; i++) {
            dp[i][0] = true;
        }
        dp[0][nums[0]] = true;
        for (int i = 1; i < n; i++) {
            for (int j = 1; j <= target; j++) {
                if (j >= nums[i]) {
                    dp[i][j] = dp[i - 1][j] | dp[i - 1][j - nums[i]];
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        return dp[n-1][target];
    }
};

一维数组

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n = nums.size();
        int sum = 0, maxNum = 0;
        for(auto& num : nums) {
            sum += num;
            maxNum = max(maxNum, num);
        }
        int target = sum / 2;
        if(sum & 1 || target < maxNum) {
            return false;
        }
        vector<bool> dp(target, false);
        dp[0] = true;
        for (int i = 1; i < n; i++) {
            for (int j = target; j >= nums[i]; j--) {
                dp[j] = dp[j] | dp[j - nums[i]];
            }
        }
        return dp[target];
    }
};

102. 加减的目标值

题目:

给定一个正整数数组 nums 和一个整数 target
向数组中的每个整数前添加 ‘+’ 或 ‘-’ ,然后串联起所有整数,可以构造一个 表达式

  • 例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式 “+2-1” 。

返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例:

输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 5 种方法让最终目标和为 3 。
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3

提示:

  • 1 <= nums.length <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums[i]) <= 1000
  • -1000 <= target <= 1000

思路:

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        int sum = 0;
        for (auto& n : nums) {
            sum += n;
        }
        if ((target + sum) & 1 != 0 || sum < target) {
            return 0;
        }
         
        vector<int> dp((target + sum) / 2 + 1, 0);
        dp[0] = 1;
        for (auto& n : nums) {
            for (int j = dp.size() - 1; j >= n; --j) {
                dp[j] += dp[j - n];
            }
        }
        return dp.back();
    }
};
举报

相关推荐

0 条评论