✏️오늘의 문제
class Solution {
public int arrayPairSum(int[] nums) {
int sum = 0;
Arrays.sort(nums);
for(int i =0 ; i < nums.length; i++){
if(i%2==0){
sum += nums[i];
}
}
return sum;
}
}
문제의 목표는 주어진 배열을 두 개의 그룹으로 나누어 각 그룹의 최소값의 합을 최대화하는 것입니다. 배열의 길이는 항상 짝수이므로, 각 그룹에는 n/2개의 요소가 포함됩니다.
정렬의 필요성
짝수 인덱스 선택
시간 복잡도
주어진 코드는 LeetCode 561번 문제 "Array Partition I"를 해결하는 방법 중 하나로, 배열의 최소값의 합을 최대화하기 위해 빈도 기반의 접근 방식을 사용합니다. 아래에 코드의 각 부분을 자세히 설명하겠습니다.
class Solution {
public int arrayPairSum(int[] nums) {
int max = Integer.MIN_VALUE; // 배열의 최대값을 찾기 위한 변수
int min = Integer.MAX_VALUE; // 배열의 최소값을 찾기 위한 변수
// 배열의 최대값과 최소값을 찾음
for (int num : nums) {
max = Math.max(num, max); // 최대값 업데이트
min = Math.min(num, min); // 최소값 업데이트
}
// 빈도 배열 초기화
int[] counts = new int[max - min + 1];
// 각 숫자의 빈도 계산
for (int num : nums) {
counts[num - min]++; // 해당 숫자의 빈도 증가
}
int res = 0; // 결과 변수, 최소값의 합을 저장
int idx = 0; // 빈도 배열의 인덱스
// 쌍을 만들면서 최소값의 합 계산
for (int i = 0; i < nums.length / 2; i++) {
// 다음 사용 가능한 최소값 찾기
while (counts[idx] == 0) {
idx++; // 인덱스를 증가시켜 빈도 배열에서 0이 아닌 값을 찾음
}
res += idx; // 현재 인덱스의 값을 결과에 추가
counts[idx]--; // 사용한 숫자의 빈도 감소
// 다음 사용 가능한 두 번째 최소값 찾기
while (counts[idx] == 0) {
idx++; // 다음 인덱스로 이동
}
counts[idx]--; // 두 번째 숫자의 빈도 감소
}
// 최소값의 합에 최소값 * (배열 길이 / 2)을 추가하여 결과 반환
return res + nums.length / 2 * min;
}
}
최대값과 최소값 찾기
max
와 min
변수를 초기화하여 배열의 최대값과 최소값을 찾습니다. 이를 통해 빈도 배열을 생성할 때 필요한 범위를 결정합니다.빈도 배열 생성
int[] counts = new int[max - min + 1];
: 최대값과 최소값의 차이를 기반으로 빈도 배열을 초기화합니다. 이 배열은 각 숫자의 출현 횟수를 기록합니다.for
루프에서 각 숫자의 빈도를 증가시킵니다. counts[num - min]++
는 해당 숫자의 빈도를 기록합니다.최소값의 합 계산
for (int i = 0; i < nums.length / 2; i++)
: 배열의 길이의 절반만큼 반복합니다. 이는 쌍을 만들기 위해 필요한 반복 횟수입니다.while (counts[idx] == 0)
: 빈도 배열에서 0이 아닌 값을 찾기 위해 인덱스를 증가시킵니다. 이 과정에서 최소값을 찾습니다.res += idx;
: 현재 인덱스의 값을 결과에 추가합니다.while
루프에서 다음 최소값을 찾고 빈도를 감소시킵니다.결과 반환
return res + nums.length / 2 * min;
: 계산된 최소값의 합에 최소값을 쌍의 수 만큼 곱하여 최종 결과를 반환합니다.