Partition Equal Subset Sum


Question

Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

Note: Each of the array element will not exceed 100. The array size will not exceed 200.

Solution

知道是用 DP 解,但想不出來,所以第一遍直接看解答。 這題講白了其實跟 house robber 核心概念很像,就是取或不取。我們知道要分成兩個 subset,每一個 subset 加總起來的值會是 sum/2。因此,在遍歷 array 的過程中,會面臨到該取這個值或不該取這個值。

state: dp[i][j] 代表前 i 個數能否加總成 j(sum/2) function: 如果決定不取,那麼 dp[i][j] = dp[i - 1][j];如果決定要取,那 dp[i][j] = dp[i - 1][j - nums[i - 1]]。不取的情況比較好想,取的情況可以想成,如果我取了當前這個值,那就代表我前 i - 1 個的加總要等於 j - nums[i - 1] (用 nums[i - 1] 是因為 state 定義前 i 個,試想前三個其實是代表 index 只到 2)

initialize: dp[nums.length + 1][sum + 1]; dp[0][0] = true, dp[i][0] = true, dp[0][j] = false; answer: 求 dp[nums.length][sum]

    public boolean canPartition(int[] nums) {
        int sum = 0;
        for (int num : nums) {
            sum += num;
        }
        if (sum % 2 == 1) {
            return false;
        }

        sum /= 2;

        boolean[][] dp = new boolean[nums.length + 1][sum + 1];
        dp[0][0] = true;

        for (int i = 1; i <= nums.length; i++) {
            dp[i][0] = true;
        }

        for (int i = 1; i <= sum; i++) {
            dp[0][i] = false;
        }

        for (int i = 1; i <= nums.length; i++) {
            for (int j = 1; j <= sum; j++) {
                if (j >= nums[i - 1]) {
                    dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]];
                }
            }
        }
        return dp[nums.length][sum];
    }

results matching ""

    No results matching ""