[494] leetcode目標と(動的プログラミング、DFS)

トピックへのリンク:https://leetcode-cn.com/problems/target-sum/

考え

動的プログラミングの1次元アレイ

(1)まず、範囲を求め、全アレイsum
(2)二次元アレイ、アレイ・サイズを確立しますnums.size() * sumDP [I] [j]は、インデックスとして表されるi日付とするためj、多数の方法負等しい正ネゲート、jが負の場合、その方法およびjはその反対と同じであるためdp[i][-j]
(3)動的プログラミング式:

dp[i][j] = dp[i-1][abs(j-nums[i])] + dp[i-1][j+nums[i]]

(4)最後に返しdp[nums.size()-1][abs(S)]

複雑分析
時間複雑:O(MN)
空間の複雑:O(MN)
mは、配列の長さであり、nアレイと

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int S) {
        auto sum = accumulate(nums.begin(), nums.end(), 0); // 和表示范围 [-sum, sum]
        if(nums.empty() ||  S > 1000 || abs(S) > sum)       // 超出表示范围
            return 0;

        vector<vector<int>> dp(nums.size(),vector<int>(sum+1,0));
        //dp[i][j]表示为到下标i为止和为j的方法数,由于负数等于正数取反,如果j是负数,其方法与j是相反数时相同,即dp[i][-j];
        dp[0][nums[0]] = (nums[0] == 0) ? 2 : 1;    // 取第一个数的方法数;nums[0]==0时正负号都可加

        for(int i = 1 ; i < nums.size();++i){
            for(int j = 0 ; j <= sum; ++j){
                int count1 = abs(j-nums[i]) > sum ? 0 : dp[i-1][abs(j-nums[i])];   // +号
                int count2 = ( j + nums[i] ) > sum ? 0 : dp[i-1][j+nums[i]];       // -号
                dp[i][j] = count1 + count2;
            }
        }
        return dp[nums.size()-1][abs(S)];
    }
};

ここに画像を挿入説明

2次元アレイダイナミックプログラミング

おすすめ

転載: blog.csdn.net/zjwreal/article/details/91394765