해당 포스는 이전 포스트에서 말했던 splice 메서드의 시간복잡도 문제를 해결하기 위해
JavaScript에서 배열을 정렬하고 요소를 제거하는 작업을 최적화하는 방법에 대해 알아보려 한다.
특히 splice
메서드를 사용하였을때 발생한 문제와, 이를 최적화한 코드 작성에 대해 중점적으로 다루겠다.
입력 데이터의 크기가 매우 클 때, 특히 score
배열의 길이가 최대 1,000,000인 경우, 정렬 및 요소 제거 작업에서 성능 문제가 발생할 수 있다.
특히, Array.prototype.sort()
메서드는 O(n log n)의 시간 복잡도를 가지며, 대규모 배열에서 성능 저하의 주요 원인이 된다.
function Restriction(k, m, score) {
if (k < 3 || k > 9) return false;
if (m < 3 || m > 10) return false;
if (score.length < 7 || score.length > 1000000) return false;
if (score.some(s => s < 1 || s > k)) return false;
return true;
}
function solution(k, m, score) {
if (!Restriction(k, m, score)) {
throw new Error("Restriction Violation!");
}
// 배열을 내림차순으로 정렬
score.sort((a, b) => b - a);
let totalValue = 0;
while (score.length >= m) {
// m 개씩 뽑아서 상자를 만든다.
let box = score.splice(0, m);
// 상자의 최저 점수를 구한다.
let minScore = Math.min(...box);
// 상자의 가치를 계산한다.
totalValue += minScore * m;
}
return totalValue;
}
splice
사용: splice
는 배열의 중간에서 요소를 제거할 때 비효율적이다. 특히 큰 배열에서는 성능이 저하되는 문제가 발생한다.Math.min(...box)
를 사용하여 최소값을 계산하는 방식은 추가적인 연산을 필요로 한다.while
루프는 조건을 반복적으로 확인하므로 추가적인 연산이 발생한다.splice
제거: splice
를 사용하지 않고 인덱스를 이용하여 고정된 크기의 상자를 만든다.for
루프를 사용하여 불필요한 반복을 줄인다.function Restriction(k, m, score) {
if (k < 3 || k > 9) return false;
if (m < 3 || m > 10) return false;
if (score.length < 7 || score.length > 1000000) return false;
if (score.some(s => s < 1 || s > k)) return false;
return true;
}
function solution(k, m, score) {
if (!Restriction(k, m, score)) {
throw new Error("Restriction Violation!");
}
// 배열을 내림차순으로 정렬
score.sort((a, b) => b - a);
let totalValue = 0;
// m 개씩 상자를 만들어 계산한다.
for (let i = 0; i <= score.length - m; i += m) {
// 상자의 최저 점수를 구한다.
let minScore = score[i + m - 1];
// 상자의 가치를 계산한다.
totalValue += minScore * m;
}
return totalValue;
}
// 예제 테스트
let k = 3;
let m = 4;
let score1 = [1, 2, 3, 1, 2, 3, 1];
console.log(solution(k, m, score1)); // 8
let k2 = 4;
let m2 = 3;
let score2 = [4, 1, 2, 2, 4, 4, 4, 4, 1, 2, 4, 2];
console.log(solution(k2, m2, score2)); // 33
splice
사용 제거:
splice
를 사용하여 요소를 제거하는 방식 대신, for
루프와 인덱스를 사용하여 필요한 요소를 참조한다. 이를통해 메모리 사용을 최적화하고 성능을 향상시킨다.최소값 계산 최적화:
Math.min
함수 호출을 피하면서도 정확한 최소값을 얻을 수 있게 한다.루프 최적화:
for
루프를 사용하여 일정한 간격으로 인덱스를 증가시키며 상자를 만든다.최적화 과정을 통해 불필요한 배열 변형을 피하고, 최소값 계산을 단순화하며, 반복문을 최적화하여 시간 초과 문제를 해결할 수 있었다.