ptmdmusique icon

https://leetcode.com/problems/partition-equal-subset-sum/sub

ptmdmusique | PRO | 09/25/19 01:10:42 AM UTC | 0 ⭐ | 224 👁️ | Never ⏰ | []
Java |

2.58 KB

|

None

|

0 👍

/

0 👎

class Solution {
    public int[][] remain;
    
    public int sum(int[] arr) {
        int total = 0;
        for (int data : arr) {
            total += data;
        }
        
        return total;
    }
    
    /*
        Since we are finding if there is a way to partition the set 
            into 2 subsets that have equal sum (let's call it x1 and x2)
            then we can check if there is a subset that has 
            the sum equal to half
        Because x1 = x2 and x1 + x2 = total => x1 = x2 = total / 2
    */
    
    /*
        To find if there is a subset that can be sum up to a certain number,
            the idea is have a 2d array[][] where arr[i][j] represents
                if we haven't gone through that path (0), 
                can't be summed up to sum (-1),
                can be summed up to sum (1).
        We can then search for by going: 
            arr[half][i] -> arr[half - i][i'] -> ... until arr[n][m] = 0
            where i, i', m belongs to nums[]
    */
    public boolean canPartition(int[] nums) {
        int total = sum(nums);
        //Meaningless if the total is odd
        if (total % 2 != 0) {
            return false;
        }
        
        int half = total / 2;   //Find half of the total sum
        remain = new int[half + 1][nums.length];
        
        //Fill the base cases
        for (int indx = 0; indx < nums.length; indx++) {
            remain[0][indx] = 1;
        }
        
        //Fill out the rest
        fillTable(nums, half, nums.length - 1);
        
        boolean found = false;
        for(int data : remain[half]) {
            if (data == 1) {
                found = true;
                break;
            }
        }
        
        //Check if there is a subset that has the sum equals to that half
        return found;
    }
    
    public boolean fillTable(int[] nums, int curSum, int index) {
        if (curSum < 0 || index < 0) {
            //Invalid
            return false;
        } 
        
        //No need to check again
        if (remain[curSum][index] != 0) {
            return remain[curSum][index] == 1 ? true : false;    
        }
        
        //Default
        remain[curSum][index] = -1;
        boolean found = false;
        
        for (int indx = index; indx > -1 && found != true; indx--) {
            found = fillTable(nums, curSum - nums[indx], indx - 1);
        }    
        
        if (found == true) {
            remain[curSum][index] = 1;    
        }
        
        return found;
    }
    
}

Comments