[프로그래머스] 최고의 집합
문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/12938
접근 방식
모든 집합을 구할 필요가 없다.
이 문제의 핵심은, 집합의 원소들이 중앙 값에 근접할 수록 각 원소의 곱이 최대가 된다는 것이다.
예제를 살펴보면, 9를 만들 수 있는 집합은 {1, 8}, {2, 7}, {3, 6}, {4, 5}
가 있다. 이 중에서 각 원소의 곱이 최대인 것은 마지막인 {4, 5}
이다.
이와 관련된 수학의 부등식이 존재한다. 바로 산술-기하 평균 부등식이다.
앞서 말했던, 이론을 증명하는 내용을 담고 있다.
나도 위의 부등식은 알지 못했지만, 예제를 살펴보고 테스트 케이스를 작성하던 과정에서 법칙을 깨닫게 되었다.
ex) s=3, n=16일 때, 최고의 집합은 {5, 5, 6} 이다
ex) s=2, n=8일 때, 최고의 집합은 {4, 4} 이다
결과
소스 코드
import java.util.*;
class Solution {
public int[] solution(int n, int s) {
// 예외 처리
if (s < n) {
return new int[] {-1};
}
// 기본 몫과 나머지 계산
int num = s / n;
int remain = s % n;
// 정답 배열 초기화
int[] answer = new int[n];
Arrays.fill(answer, num); // 모든 원소를 기본 몫으로 채움
// 나머지 만큼 뒤에서부터 +1씩 분배
for (int i = 0; i < remain; i++) {
answer[n - 1 - i] += 1;
}
return answer;
}
}
모든 원소가 비교적 균등해야 한다.
중복을 허용하기 때문에, s가 n으로 나누어 떨어지면, 몫이 정답이 되고
나누어 떨어지지 않는다면, 몫으로 전부 분배하되, 뒤에서부터 하나씩 1을 더해서 값을 수정하면 된다.