[LeetCode] 494. Target Sum 目標和
阿新 • • 發佈:2018-09-29
數字 div .cn array assign url || first cnblogs
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols +
and -
. For each integer, you should choose one from +
and -
as its new symbol.
Find out how many ways to assign symbols to make sum of integers equal to target S.
Example 1:
Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5 Explanation: -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 There are 5 ways to assign symbols to make the sum of nums be target 3.
Note:
- The length of the given array is positive and will not exceed 20.
- The sum of elements in the given array will not exceed 1000.
- Your output answer is guaranteed to be fitted in a 32-bit integer.
給一個由非負整數組成的數組,和一個目標值,給數字前面加上正號或負號,然後求和,問和目標值相等的情況有多少。
解法:遞歸,循環數組裏的數字,調用遞歸函數,分別對目標值進行加上和減去當前數字,再調用遞歸,這樣就會涵蓋所有情況,若目標值為0了,則結果res自增1。
Java:
public int findTargetSumWays(int[] nums, int s) { int sum = 0; for (int n : nums) sum += n; return sum < s || (s + sum) % 2 > 0 ? 0 : subsetSum(nums, (s + sum) >>> 1); } public int subsetSum(int[] nums, int s) { int[] dp = new int[s + 1]; dp[0] = 1; for (int n : nums) for (int i = s; i >= n; i--) dp[i] += dp[i - n]; return dp[s]; }
Python:
class Solution(object): def findTargetSumWays(self, nums, S): if not nums: return 0 dic = {nums[0]: 1, -nums[0]: 1} if nums[0] != 0 else {0: 2} for i in range(1, len(nums)): tdic = {} for d in dic: tdic[d + nums[i]] = tdic.get(d + nums[i], 0) + dic.get(d, 0) tdic[d - nums[i]] = tdic.get(d - nums[i], 0) + dic.get(d, 0) dic = tdic return dic.get(S, 0)
C++:
class Solution { public: int findTargetSumWays(vector<int>& nums, int s) { int sum = accumulate(nums.begin(), nums.end(), 0); return sum < s || (s + sum) & 1 ? 0 : subsetSum(nums, (s + sum) >> 1); } int subsetSum(vector<int>& nums, int s) { int dp[s + 1] = { 0 }; dp[0] = 1; for (int n : nums) for (int i = s; i >= n; i--) dp[i] += dp[i - n]; return dp[s]; } };
C++:
class Solution { public: int findTargetSumWays(vector<int>& nums, int S) { int res = 0; helper(nums, S, 0, res); return res; } void helper(vector<int>& nums, int S, int start, int& res) { if (start >= nums.size()) { if (S == 0) ++res; return; } helper(nums, S - nums[start], start + 1, res); helper(nums, S + nums[start], start + 1, res); } };
C++: 使用dp記錄中間值優化
class Solution { public: int findTargetSumWays(vector<int>& nums, int S) { vector<unordered_map<int, int>> dp(nums.size()); return helper(nums, S, 0, dp); } int helper(vector<int>& nums, int sum, int start, vector<unordered_map<int, int>>& dp) { if (start == nums.size()) return sum == 0; if (dp[start].count(sum)) return dp[start][sum]; int cnt1 = helper(nums, sum - nums[start], start + 1, dp); int cnt2 = helper(nums, sum + nums[start], start + 1, dp); return dp[start][sum] = cnt1 + cnt2; } };
C++:
class Solution { public: int findTargetSumWays(vector<int>& nums, int S) { int n = nums.size(); vector<unordered_map<int, int>> dp(n + 1); dp[0][0] = 1; for (int i = 0; i < n; ++i) { for (auto &a : dp[i]) { int sum = a.first, cnt = a.second; dp[i + 1][sum + nums[i]] += cnt; dp[i + 1][sum - nums[i]] += cnt; } } return dp[n][S]; } };
C++:
class Solution { public: int findTargetSumWays(vector<int>& nums, int S) { unordered_map<int, int> dp; dp[0] = 1; for (int num : nums) { unordered_map<int, int> t; for (auto a : dp) { int sum = a.first, cnt = a.second; t[sum + num] += cnt; t[sum - num] += cnt; } dp = t; } return dp[S]; } };
類似題目:
[LeetCode] 282. Expression Add Operators 表達式增加操作符
[LeetCode] 494. Target Sum 目標和