1)그리디 알고리즘
이 문제는 그리디 알고리즘과 정렬을 이용하여 해결할 수 있습니다. 주어진 수들을 절대값을 기준으로 정렬한 후, 큰 수부터 차례대로 두 그룹에 배분하면 됩니다. 배분하는 기준은 그룹의 합을 최소화하는 것입니다.
이를 Java 코드로 구현하면 다음과 같습니다.
java
Copy code
import java.util.*;
class Solution {
public int solution(int[] numbers) {
int sum1 = 0, sum2 = 0;
Integer[] numbersCopy = Arrays.stream(numbers).boxed().toArray(Integer[]::new);
Arrays.sort(numbersCopy, Comparator.comparingInt(Math::abs).reversed());
for (int number : numbersCopy) {
if (sum1 > sum2) {
sum2 += number;
} else {
sum1 += number;
}
}
return Math.abs(sum1 - sum2);
}
}
먼저 입력 배열을 복사하면서 Integer 타입으로 바꾸고, 절대값을 기준으로 내림차순으로 정렬합니다. 그 다음으로 각 숫자를 큰 수부터 차례대로 두 그룹에 배분하는데, 그룹의 합이 작은 쪽에 배분합니다. 이렇게 모든 수를 배분한 후에 두 그룹의 합의 차이를 계산하여 반환하면 됩니다.
2)DP
이 문제는 Dynamic Programming(DP)을 활용하여도 풀 수 있습니다. 그룹의 합의 차이가 최소가 되려면 모든 원소의 합을 반으로 나눈 값과 가장 가까운 값을 구해야 합니다. DP를 이용하여 가능한 모든 합의 경우를 구하고 그 중에서 가장 원소의 합의 절반에 가까운 값을 찾아 그 차이를 반환하면 됩니다.
아래는 이를 구현한 Java 코드입니다:
import java.util.*;
public class Solution {
public int solution(int[] A) {
// Convert A to the absolute values of its elements
for (int i = 0; i < A.length; i++) {
A[i] = Math.abs(A[i]);
}
// Calculate the sum of elements in A
int S = 0;
for (int a : A) {
S += a;
}
// Initialize a list to store the possible sums
int[] dp = new int[S + 1];
dp[0] = 1;
// Calculate the possible sums
for (int a : A) {
for (int j = S; j >= 0; j--) {
if (dp[j] == 1 && j + a <= S) {
dp[j + a] = 1;
}
}
}
// Find the minimum absolute value of the sums
int result = S;
for (int i = 0; i <= S / 2; i++) {
if (dp[i] == 1) {
result = Math.min(result, S - 2 * i);
}
}
return result;
}
}
이 코드는 입력받은 숫자들의 절대값의 합을 계산한 후, 그 합을 2로 나눠 반값(halfSum)을 구합니다. 그리고 가능한 모든 합을 저장할 boolean 배열을 선언합니다. 이 배열의 인덱스는 합을, 값은 그 합이 가능한지 여부를 나타냅니다. 그 다음 숫자들을 순회하면서 해당 숫자를 포함하여 만들 수 있는 합을 dp 배열에 표시합니다. 마지막으로 dp 배열을 반값부터 내림차순으로 검사하여 첫 번째 true 값을 찾으면 그 인덱스가 최대로 가능한 그룹의 합입니다. 이 값을 원소의 합에서 뺀 뒤 2를 곱하면 그룹의 합의 최소 차이를 구할 수 있습니다.