-
Notifications
You must be signed in to change notification settings - Fork 1
/
PartitionEqualSubsetSum.java
144 lines (116 loc) · 4.5 KB
/
PartitionEqualSubsetSum.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package com.leetcode;
import java.util.HashMap;
/**
Example 1:
Input: nums = [1,5,11,5]
Output: true
Explanation: The array can be partitioned as [1, 5, 5] and [11].
Example 2:
Input: nums = [1,2,3,5]
Output: false
Explanation: The array cannot be partitioned into equal sum subsets.
**/
public class PartitionEqualSubsetSum {
/*
In the worst case where there is no overlapping calculation,
the maximum number of entries in the memo would be N * M where M is total sum / 2 and N is no of elements
*/
//https://leetcode.com/problems/partition-equal-subset-sum/
class SolutionMemo{
public boolean canPartition(int[] nums) {
HashMap<String,Boolean> memo = new HashMap<>();
int n = nums.length;
int total = 0;
for(int i : nums){
total+= i;
}
if(total %2 != 0) return false;
return canPartition(0,0,nums,total,memo);
}
public boolean canPartition(int pos,int sum , int [] nums, int total , HashMap<String,Boolean> memo){
String key = pos+""+sum;
if(memo.containsKey(key)) return memo.get(key);
if(sum > total/2) return false;
if(pos >= nums.length) return false;
if(sum == total/2) return true; // second half exist as total is even
//To take or not take nums[pos]
boolean result = canPartition(pos+1,sum,nums,total,memo) || canPartition(pos+1,sum+nums[pos],nums,total,memo);
memo.put(key,result);
return result;
}
}
//map compare heavy
class SolutionTLE {
/**
- Given total sum is even number find a subset whose sum - total/2 so other subset will be total/2 as well
**/
public boolean canPartition(int[] nums) {
HashMap<Node,Boolean> memo = new HashMap<>();//memo to store at n and sum Pair has value computed
int totalSum = 0;
// find sum of all array elements
for (int num : nums) {
totalSum += num;
}
// if totalSum is odd,it cannot be partitioned into equal sum subset
if (totalSum % 2 != 0) return false;
int half = totalSum / 2;
int n = nums.length;
return canPartitionRec(nums, n - 1, half,memo);
}
public boolean canPartitionRec(int[] nums, int n, int subSetSum, HashMap<Node,Boolean> memo) {
// Base Cases
if (subSetSum == 0)
return true;
if (n == 0 || subSetSum < 0)
return false;
Node node = new Node(n,subSetSum);
if(memo.containsKey(node)) return memo.get(node);
//choose or not to choose
boolean result = canPartitionRec(nums, n - 1, subSetSum - nums[n - 1],memo) || canPartitionRec(nums, n - 1, subSetSum,memo);
memo.put(node,result);
return result;
}
class Node{
int n;
int sum;
public Node(int n , int sum){
this.n = n;
this.sum = sum;
}
public boolean equals(Node n , Node m){
if(n.n != m.n || n.sum != m.sum) return false;
return true;
}
}
}
class Solution {
public boolean canPartition(int[] nums) {
int totalSum = 0;
// find sum of all array elements
for (int num : nums) {
totalSum += num;
}
// if totalSum is odd, it cannot be partitioned into equal sum subset
if (totalSum % 2 != 0) return false;
int subSetSum = totalSum / 2;
int n = nums.length;
Boolean[][] memo = new Boolean[n + 1][subSetSum + 1];
return dfs(nums, n - 1, subSetSum, memo);
}
public boolean dfs(int[] nums, int n, int subSetSum, Boolean[][] memo) {
// Base Cases
if (subSetSum == 0)
return true;
if (n == 0 || subSetSum < 0)
return false;
// check if subSetSum for given n is already computed and stored in memo
if (memo[n][subSetSum] != null)
return memo[n][subSetSum];
boolean result = dfs(nums, n - 1, subSetSum - nums[n - 1], memo) ||
dfs(nums, n - 1, subSetSum, memo);
// store the result in memo
memo[n][subSetSum] = result;
return result;
}
}
}