• LeetCode 494 目标和


    题目链接:LeetCode 494 目标和

    题目大意:

    题解:

    回溯

    可以使用回溯的方法遍历所有的表达式,回溯过程中维护一个计数器\(count\),当遇到一种表达式的结果等于目标数\(target\)时,将\(count\)的值加\(1\)。遍历完所有的表达式之后,即可得到结果等于目标数\(target\)的表达式的数目。

    class Solution {
    private:
        int cnt = 0;
    
    public:
        int findTargetSumWays(vector<int>& nums, int target) {
            dfs(nums, target, 0, 0);
            return cnt;
        }
    
        void dfs(vector<int>& nums, int target, int index, int sum) {
            if (index == nums.size()) {
                if (sum == target) {
                    cnt++;
                }
            } else {
                dfs(nums, target, index + 1, sum + nums[index]);
                dfs(nums, target, index + 1, sum - nums[index]);
            }
        }
    };
    

    动态规划

    参考自LeedCode官方题解
    记数组元素和为\(sum\),添加\(-\)号的元素和为\(neg\),则可得到表达式:

    \[(sum - neg) - neg = sum - 2 \times neg = target \]

    \[neg = \frac{sum - target}{2} \]

    由于数组中都是非负整数,所以\(neg\)也必须是非负整数,因此\(sum - target\)必须是非负偶数,若不符合条件可直接返回\(0\)
    若上式成立,问题转化成在数组\(nums\)中选取若干元素,使得这些元素之和等于\(neg\),计算选取元素的方案数。我们可以使用动态规划的方法求解。
    \(dp[i][j]\)表示在数组\(nums\)的前\(i\)个数中选取元素,使得这些元素之和等于\(j\)的方案数。
    状态转移方程:

    \[\left\{ \begin{array}{l} dp[i][j] = dp[i - 1][j],j<nums[i] \\ dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]], j \geq nums[i] \end{array} \right. \]

    边界条件为\(dp[0][0] = 1\)
    由于\(dp\)的每一行的计算只和上一行有关,因此可以使用滚动数组的方式,去掉\(dp\)的第一个维度,将空间复杂度优化到\(O(neg)\)

    class Solution {
    public:
        int findTargetSumWays(vector<int>& nums, int target) {
            int sum = 0;
            for (int num : nums) {
                sum += num;
            }
            int temp = sum - target;
            if (temp < 0 || temp & 1) {
                return 0;
            }
            temp >>= 1;
            vector<int> dp(temp + 1);
            dp[0] = 1;
            for (int num : nums) {
                for (int j = temp; j >= num; --j) {
                    dp[j] += dp[j - num];
                }
            }
            return dp[temp];
        }
    };
    
  • 相关阅读:
    iOS 数字滚动 类似于老
    iOS 实现转盘的效果
    iOS 摇一摇的功能
    APP上架证书无效:解决
    iOS--UIAlertView与UIAlertController和UIAlertAction之间的事儿
    ios 获取字符串所需要占用的label的高度
    适配----Autolayout
    OC中 block 的用法
    微信小程序如何播放腾讯视频?
    IOS-UICollectionView
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/15862826.html
Copyright © 2020-2023  润新知