티스토리 뷰
[LeetCode - Daily Challenge] 416. Partition Equal Subset Sum
Jaime.Lee 2021. 12. 12. 22:30Problem
Given a non-empty array nums 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.
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.
Constraints:
- 1 <= nums.length <= 200
- 1 <= nums[i] <= 100
Solution
양의 정수로 이루어진 배열이 주어질 때 합이 같은 두 개의 부분집합으로 나눌 수 있는지 확인하는 문제입니다.
public class Solution {
public boolean canPartition(int[] nums) {
if (nums == null || nums.length < 2) {
return false;
}
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 != 0) { // (1)
return false;
}
sum /= 2;
boolean[] dp = new boolean[sum + 1]; // (2)
dp[0] = true; // (3)
for (int i = 1; i < nums.length; i++) {
int current = nums[i - 1];
for (int j = sum; j >= current; j--) {
dp[j] |= dp[j - current]; // (4)
}
}
return dp[sum];
}
}
- 배열의 합이 홀수이면 합이 같은 두 부분 배열로 나눌 수 없습니다.
- 합이 같은 두 부분 배열로 나누기 위해선 배열의 전체 합을 2로 나눈 값을 합으로 가지는 두 배열을 만들어야 하므로 DP 배열의 길이를 합의 절반으로 설정합니다.
- 초기 값을 설정합니다.
- 부분 배열의 합이 되어야 할 값부터 출발하여 현재 인덱스에 해당하는 값까지 1씩 줄여주면서 반복합니다. j번째 값이 j에서 current만큼 뺐을 때 0이 되면 sum을 만들 수 있다는 뜻인데요, 그 이유를 1번 예제를 이용해 설명하겠습니다.
sum = (1 + 5 + 11 + 5) / 2 = 11
i = 1:
current = 1 (nums의 0번째 값)
j = 11 ~ 1:
dp[11] = dp[11] || dp[10] = false;
dp[10] = dp[10] || dp[9] = false;
dp[9] = dp[9] || dp[8] = false;
...
dp[1] = dp[1] || dp[0] = true;
현재까지 DP 배열
[true, true, false, false, false, false, false, false, false, false, false, false]
i = 2:
current = 5 (nums의 1번째 값)
j = 11 ~ 5
dp[11] = dp[11] || dp[6] = false;
dp[10] = dp[10] || dp[5] = false;
dp[9] = dp[9] || dp[4] = false;
dp[8] = dp[8] || dp[3] = false;
dp[7] = dp[7] || dp[2] = false;
dp[6] = dp[6] || dp[1] = true;
dp[5] = dp[5] || dp[0] = true;
현재까지 DP 배열
[true, true, false, false, false, true, true, false, false, false, false, false]
i = 3:
current = 11 (nums의 2번째 값)
j = 11
dp[11] = dp[11] || dp[0] = true;
현재까지 DP 배열
[true, true, false, false, false, true, true, false, false, false, false, true]
## Test
```java
package io.lcalmsky.leetcode.partition_equal_subset_sum;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class SolutionTest {
@Test
void givenArray_whenSumSubsets_thenEqualsPartition() {
assertAll(
() -> test(new int[]{1, 5, 11, 5}, true),
() -> test(new int[]{1, 2, 3, 4, 5}, false)
);
}
private void test(int[] given, boolean expected) {
// when
Solution solution = new Solution();
boolean actual = solution.canPartition(given);
// then
assertEquals(expected, actual);
}
}
'Algorithm > LeetCode' 카테고리의 다른 글
[LeetCode - Daily Challenge] 790. Domino and Tromino Tiling (0) | 2021.12.14 |
---|---|
[LeetCode - Daily Challenge] 1446. Consecutive Characters (0) | 2021.12.13 |
[LeetCode - Daily Challenge] 878. Nth Magical Number (0) | 2021.12.11 |
[LeetCode - Daily Challenge] 1306. Jump Game III (0) | 2021.12.09 |
[LeetCode - Daily Challenge] 1290. Convert Binary Number in a Linked List to Integer (0) | 2021.12.08 |
- Total
- Today
- Yesterday
- spring boot application
- Spring Boot Tutorial
- intellij
- Spring Boot
- Spring Boot JPA
- QueryDSL
- Linux
- Java
- gRPC
- Spring Data JPA
- 헥사고날 아키텍처
- leetcode
- 함께 자라기
- 스프링 데이터 jpa
- spring boot jwt
- 클린 아키텍처
- 스프링 부트 튜토리얼
- @ManyToOne
- r
- JSON
- 스프링부트
- Jackson
- JPA
- proto3
- spring boot app
- 알고리즘
- 스프링 부트 회원 가입
- 스프링 부트
- 함께 자라기 후기
- 스프링 부트 애플리케이션
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |