코딩테스트는 현대 소프트웨어 개발에서 매우 중요한 요소입니다. 기업들은 개발자의 문제 해결 능력을 평가하기 위해 다양한 알고리즘 문제를 출제합니다. 오늘은 배열에서 K번째 수를 찾는 문제를 다루어 보겠습니다. 이 문제는 배열을 다루는 기본적인 알고리즘 기술을 쌓을 수 있는 좋은 예시입니다.
문제 설명
주어진 배열 arr
와 정수 k
가 있을 때, arr
에서 K번째로 작은 수를 찾아 반환하시오. 배열의 인덱스는 0부터 시작합니다.
입력
- 정수 배열
arr
, 길이는 1 이상 100,000 이하. - 정수
k
, 1 이상 배열의 길이 이하.
출력
arr
에서 K번째로 작은 수를 반환한다.
예시
arr = [3, 1, 2, 4, 5], k = 2
출력:
2
설명: 배열을 오름차순 정렬하면 [1, 2, 3, 4, 5]가 되고, 2번째 수는 2입니다.
arr = [7, 10, 4, 3, 20, 15], k = 3
출력:
7
설명: 배열을 오름차순 정렬하면 [3, 4, 7, 10, 15, 20]가 되고, 3번째 수는 7입니다.
풀이 과정
이 문제는 배열을 정렬한 후에 K번째 요소를 쉽게 찾을 수 있으나, 정렬 방법에 따라 시간 복잡도가 달라질 수 있습니다. 여기서는 두 가지 접근 방식을 살펴보겠습니다.
해결 방법 1: 배열 정렬 후 K번째 수 찾기
- 배열을 오름차순으로 정렬합니다.
- K번째 수를 찾기 위해 인덱스
k - 1
에 해당하는 값을 반환합니다.
자바스크립트 코드 예시
function findKthNumber(arr, k) {
arr.sort((a, b) => a - b); // 배열을 오름차순으로 정렬
return arr[k - 1]; // K번째 수 반환
}
// 예시 실행
console.log(findKthNumber([3, 1, 2, 4, 5], 2)); // 2
console.log(findKthNumber([7, 10, 4, 3, 20, 15], 3)); // 7
위 코드에서는 단순히 배열을 정렬하고 K번째 요소를 찾았습니다. 이 방법의 시간 복잡도는 O(n log n)
입니다. 하지만, 반드시 정렬할 필요 없이 K번째 작은 수만 찾는 방법이 있습니다.
해결 방법 2: Quickselect 알고리즘
Quickselect 알고리즘은 퀵소트와 유사한 방식으로 K번째 작은 수를 찾는 방법입니다. 이 방법은 평균적으로 O(n)
의 시간 복잡도를 가집니다. 이 알고리즘은 부분 배열을 설정하고, 피벗을 선택하는 방식으로 진행됩니다.
- 배열에서 피벗 요소를 선택합니다.
- 피벗보다 작은 값은 왼쪽에, 큰 값은 오른쪽에 위치시킵니다.
- 피벗의 위치가 K번째 수의 위치와 같으면 피벗을 반환합니다.
- 그렇지 않으면, K번째 수가 좌측 또는 우측 부분 배열에 있는지에 따라 적절한 부분 배열에서 재귀적으로 Quickselect를 수행합니다.
자바스크립트 코드 예시
function quickSelect(arr, left, right, k) {
if (left === right) {
return arr[left]; // 배열에 자신만 있는 경우
}
const pivotIndex = partition(arr, left, right);
if (k === pivotIndex) {
return arr[k]; // K번째 수 발견
} else if (k < pivotIndex) {
return quickSelect(arr, left, pivotIndex - 1, k);
} else {
return quickSelect(arr, pivotIndex + 1, right, k);
}
}
function partition(arr, left, right) {
const pivot = arr[right]; // 마지막 요소를 피벗으로 선택
let i = left;
for (let j = left; j < right; j++) {
if (arr[j] <= pivot) {
[arr[i], arr[j]] = [arr[j], arr[i]]; // 교환
i++;
}
}
[arr[i], arr[right]] = [arr[right], arr[i]]; // 피벗 최종 위치
return i; // 피벗의 인덱스 반환
}
function findKthNumber(arr, k) {
return quickSelect(arr, 0, arr.length - 1, k - 1); // K-1을 인자로 전달
}
// 예시 실행
console.log(findKthNumber([3, 1, 2, 4, 5], 2)); // 2
console.log(findKthNumber([7, 10, 4, 3, 20, 15], 3)); // 7
위 코드를 통해 Quickselect 알고리즘을 이용하여 K번째 수를 효율적으로 찾을 수 있습니다. 이 방법은 평균적으로 O(n)
의 시간 복잡도를 가지므로 대규모 데이터에서 더욱 유용합니다.
결론
이번 강좌에서는 자바스크립트 코딩테스트에서 자주 다루어지는 배열에서 K번째 수 찾기 문제를 알아보았습니다. 간단한 정렬을 통해서도 문제를 해결할 수 있지만, Quickselect와 같은 효율적인 방법을 사용하여 성능을 극대화할 수 있습니다. 이러한 내용들은 실제 코딩테스트에서 매우 유용하게 활용될 수 있으므로, 꼭 연습해보시기를 권장합니다.
모든 알고리즘은 기본적인 이해가 선행된 후, 다양한 문제를 통해 응용력을 키워가는 것이 중요합니다. 다음 강좌에서는 더 다양한 배열 문제와 고급 알고리즘을 다루어 보겠습니다. 감사합니다!