Skip to content

Commit 62d298d

Browse files
author
Partho Biswas
committed
494. Target Sum
1 parent 4e2cf93 commit 62d298d

File tree

3 files changed

+180
-1
lines changed

3 files changed

+180
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ BFS, DFS, Dijkstra, Floyd–Warshall, Bellman-Ford, Kruskal, Prim's, Minimum Spa
511511

512512

513513
### 16. [Dynamic Programming](https://www.educative.io/courses/grokking-dynamic-programming-patterns-for-coding-interviews)
514+
**Follow [this](https://tinyurl.com/vmmaxbe) golden rule to approach any DP problem.**
514515
<details><summary>Leetcode problems with solutions and tutorials/videos</summary>
515516
<p>
516517

@@ -539,7 +540,8 @@ BFS, DFS, Dijkstra, Floyd–Warshall, Bellman-Ford, Kruskal, Prim's, Minimum Spa
539540
|21| **[198. House Robber](https://leetcode.com/problems/house-robber/)**| [Python](https://tinyurl.com/wu6rdaw/198_House_Robber.py)| **[Must](https://tinyurl.com/vp9v27d)** | Easy | A Gold Mine |
540541
|22| [213. House Robber II](https://leetcode.com/problems/house-robber-ii/)| [Python](https://tinyurl.com/wu6rdaw/213_House_Robber_II.py)| [Art 1](https://tinyurl.com/wwza8d5), [Art 2](https://tinyurl.com/qtqwcl4) | Medium | --- |
541542
|23| [337. House Robber III](https://leetcode.com/problems/house-robber-iii/)| [Python](https://tinyurl.com/wu6rdaw/337_House_Robber_III.py)| **[Art 1](https://tinyurl.com/yd8zjvvj)** | Medium | **[Another gold mine](https://tinyurl.com/yd8zjvvj)**, hidden greedy and DFS |
542-
|24| [416. Partition Equal Subset Sum](https://tinyurl.com/rmf5upz)| [Python](https://tinyurl.com/wu6rdaw/416_Partition_Equal_Subset_Sum.py)| **[educative.io](https://tinyurl.com/wpxxyjy)**, [Art 1](https://tinyurl.com/we99l2n), [Vid 1](https://tinyurl.com/vvtavaw), [Vid 2](https://tinyurl.com/wabhu46), [Vid 3](https://tinyurl.com/sk89wa3), [Vid 4](https://tinyurl.com/z352yjj) | Medium | **0/1 Knapsack**, Very important |
543+
|24| **[416. Partition Equal Subset Sum](https://tinyurl.com/rmf5upz)** | [Python](https://tinyurl.com/wu6rdaw/416_Partition_Equal_Subset_Sum.py)| **[educative.io](https://tinyurl.com/wpxxyjy)**, [Art 1](https://tinyurl.com/we99l2n), [Vid 1](https://tinyurl.com/vvtavaw), [Vid 2](https://tinyurl.com/wabhu46), [Vid 3](https://tinyurl.com/sk89wa3), [Vid 4](https://tinyurl.com/z352yjj) | Medium | **0/1 Knapsack**, Very important |
544+
|25| **[494. Target Sum](https://tinyurl.com/ro8wdkz)** | [Python](https://tinyurl.com/wu6rdaw/494_Target_Sum.py)| **[educative.io](https://tinyurl.com/wfhzh29)**, **[MUST MUST READ](https://tinyurl.com/vmmaxbe)** | Medium | **0/1 Knapsack**, Very important |
543545

544546
</p>
545547
</details>

leetcode.com/python/494_Target_Sum.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
class Solution(object):
2+
def findTargetSumWays(self, nums, S):
3+
"""
4+
:type nums: List[int]
5+
:type S: int
6+
:rtype: int
7+
"""
8+
totalSum = sum(nums)
9+
10+
# if 's + totalSum' is odd, we can't find a subset with sum equal to '(s + totalSum) / 2'
11+
if totalSum < S or (S + totalSum) % 2 == 1:
12+
return 0
13+
14+
return self.findTargetSumWaysHelper(nums, int((S + totalSum) / 2))
15+
16+
17+
def findTargetSumWaysHelper(self, nums, S):
18+
numsLen = len(nums)
19+
dp = [[0 for _ in range(S + 1)] for _ in range(numsLen)]
20+
21+
# populate the sum = 0 columns, as we will always have an empty set for zero sum
22+
for i in range(numsLen):
23+
dp[i][0] = 1
24+
25+
# with only one number, we can form a subset only when the required sum is
26+
# equal to the number
27+
for s in range(1, S + 1):
28+
dp[0][s] = 1 if nums[0] == s else 0
29+
30+
# process all subsets for all sums
31+
for i in range(1, numsLen):
32+
for j in range(1, S + 1):
33+
dp[i][j] = dp[i - 1][j] # exclude the number
34+
if S >= nums[i]: # include the number, if it does not exceed the sum
35+
# positive = dp[i][j] + dp[i - 1][j - nums[i]]
36+
# negative = dp[i][j] + dp[i - 1][j - nums[i]]
37+
38+
positive = j + i
39+
negative = j + (-i)
40+
dp[i][j] = positive + negative
41+
42+
# dp[i][j] = dp[i][j] + dp[i - 1][j - nums[i]]
43+
44+
# the bottom-right corner will have our answer.
45+
return dp[numsLen - 1][S]
46+
47+
48+
49+
sol = Solution()
50+
nums = [0,0,0,0,0,0,0,0,1]
51+
S = 1
52+
out = sol.findTargetSumWays(nums, S)
53+
print("Res: ", out)
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Naive solution using simple backtracking. Time Limit Exceeded
2+
class Solution(object):
3+
def canPartitionKSubsets(self, nums, k):
4+
"""
5+
:type nums: List[int]
6+
:type k: int
7+
:rtype: bool
8+
"""
9+
sumOfItems = sum(nums)
10+
if sumOfItems % k != 0: # if 's' is a an odd number, we can't have two subsets with equal sum
11+
return False
12+
if k == 1:
13+
return True
14+
return self.canPartitionHelper(nums, sumOfItems/k, 0)
15+
16+
17+
def canPartitionHelper(self, nums, sumOfItems, currentIndex):
18+
if sumOfItems == 0: # base check
19+
return True
20+
numsLen = len(nums)
21+
if numsLen == 0 or currentIndex >= numsLen:
22+
return False
23+
24+
# recursive call after choosing the number at the `currentIndex`
25+
# if the number at `currentIndex` exceeds the sum, we shouldn't process this
26+
if nums[currentIndex] <= sumOfItems:
27+
if self.canPartitionHelper(nums, sumOfItems - nums[currentIndex], currentIndex + 1):
28+
return True # Backtrack
29+
30+
# recursive call after excluding the number at the 'currentIndex'
31+
return self.canPartitionHelper(nums, sumOfItems, currentIndex + 1)
32+
33+
34+
35+
36+
#
37+
#
38+
#
39+
# # Solution using simple backtracking and memoization. Dynamic Programming on Top-Down approach. Accepted
40+
# class Solution(object):
41+
# def canPartitionKSubsets(self, nums, k):
42+
# """
43+
# :type nums: List[int]
44+
# :type k: int
45+
# :rtype: bool
46+
# """
47+
# s = sum(nums)
48+
# if s % k != 0: # if 's' is a an odd number, we can't have two subsets with equal sum
49+
# return False
50+
# dp = [[-1 for _ in range(int(s/k) + 1)] for _ in nums]
51+
# return True if self.canPartitionHelper(nums, s/k, 0, dp) == 1 else False
52+
#
53+
#
54+
# def canPartitionHelper(self, nums, sum, currentIndex, dp):
55+
# if sum == 0: # base check
56+
# return 1
57+
# numsLen = len(nums)
58+
# if numsLen == 0 or currentIndex >= numsLen:
59+
# return 0
60+
#
61+
# # if we have not already processed a similar problem
62+
# if dp[currentIndex][sum] == -1:
63+
# # recursive call after choosing the number at the `currentIndex`
64+
# # if the number at `currentIndex` exceeds the sum, we shouldn't process this
65+
# if nums[currentIndex] <= sum:
66+
# if self.canPartitionHelper(nums, sum - nums[currentIndex], currentIndex + 1, dp):
67+
# dp[currentIndex][sum] = 1
68+
# return 1 # Backtrack
69+
#
70+
# # recursive call after excluding the number at the 'currentIndex'
71+
# dp[currentIndex][sum] = self.canPartitionHelper(nums, sum, currentIndex + 1, dp)
72+
# return dp[currentIndex][sum]
73+
#
74+
#
75+
#
76+
#
77+
#
78+
# # Solution using Dynamic Programming on Bottom-up approach. Accepted
79+
# class Solution(object):
80+
# def canPartitionKSubsets(self, nums, k):
81+
# """
82+
# :type nums: List[int]
83+
# :type k: int
84+
# :rtype: bool
85+
# """
86+
# if k == 1: return True
87+
# s = sum(nums)
88+
# if s % k != 0: # if 's' is a an odd number, we can't have two subsets with equal sum
89+
# return False
90+
#
91+
# # we are trying to find a subset of given numbers that has a total sum of 's/2'.
92+
# s = int(s / k)
93+
#
94+
# numsLen = len(nums)
95+
# dp = [[False for _ in range(int(s) + 1)] for _ in range(numsLen)]
96+
#
97+
#
98+
# # populate the s=0 columns, as we can always for '0' sum with an empty set
99+
# for i in range(numsLen):
100+
# dp[i][0] = True
101+
#
102+
# # with only one number, we can form a subset only when the required sum is
103+
# # equal to its value
104+
# for j in range(1, s + 1):
105+
# dp[0][j] = nums[0] == j
106+
#
107+
# # process all subsets for all sums
108+
# for i in range(1, numsLen):
109+
# for j in range(1, s + 1):
110+
# if dp[i - 1][j]: # if we can get the sum 'j' without the number at index 'i'
111+
# dp[i][j] = dp[i - 1][j]
112+
# elif j >= nums[i]: # else if we can find a subset to get the remaining sum
113+
# dp[i][j] = dp[i - 1][j - nums[i]]
114+
#
115+
# return dp[numsLen - 1][s]
116+
#
117+
118+
119+
120+
sol = Solution()
121+
nums = [2,2,2,2,3,4,5]
122+
k = 4
123+
out = sol.canPartitionKSubsets(nums, k)
124+
print("Result: ", out)

0 commit comments

Comments
 (0)