자바스크립트/자바스크립트 알고리즘

[프로그래머스] K번째수

문제 설명

K번째수

[i, j, k] 를 원소로 가진 2차원 배열 commands 가 주어지면 i 부터 j 번째까지 배열을 자르고 정렬한 후에 k 번째에 있는 수를 배열에 담아서 return 해주는 문제입니다.

문제 풀이

먼저 commands 에 들어있는 값들을 i, j, k 라는 변수에 담아주고 싶었습니다. 이왕이면 i, j, k 라는 변수 이름보다는 의미있는 네이밍을 통해 start, end, asnwerIdx 라는 변수에 담아주었습니다. 이때 배열 디스트럭처링을 사용했습니다. 배열 디스트럭처링을 사용하면 간결하고 보다 더 가독성이 좋아진다는 장점이 있습니다.

const [start, end, answerIdx] = command;

 

start 부터 end 까지의 배열을 복사하고 정렬해주었습니다. 이때 slice 라는 메서드를 사용했는데 slice 는 원본 배열을 훼손시키지 않고 새로운 배열을 return 해준다는 장점이 있습니다. 이후 sort 를 사용해 오름차순으로 정렬해주고 answerIdx 번째 인덱스를 출력해주었습니다.

answer.push(array.slice(start - 1, end).sort((a, b) => a - b)[answerIdx-1]);

 

마지막으로 주의 할 점은 배열의 인덱스는 0 부터 시작하지만 문제에서는 0 번째가 아닌 1 번째로 정해 놓았다는 점입니다. 그러므로 시작 인덱스를 -1, 출력할 인덱스도 -1 해주며 마무리했습니다.

문제를 풀면서 배운 점

sort() 의 문제점

다른 언어의 sort 의 경우 비교 함수를 주지 않아도 알아서 오름차순으로 정렬됩니다. 하지만 JavaScript 의 sort() 의 경우 한 가지 문제점이 존재합니다. 바로 숫자의 경우 아래와 같이 정렬된다는 점입니다.

const arr = [1, 10, 111, 2, 3];
console.log(arr.sort()); // [ 1, 10, 111, 2, 3 ]

 

이는 JavaScript 의 sort() 가 암묵적으로 문자열로 형변환한 후에 정렬을 실행하기 때문에 발생하는 문제입니다. 이 문제를 해결하기 위해서는 compare 함수를 만들어서 sort() 의 인수로 넣어줘야 합니다.

const arr = [1, 10, 111, 2, 3];
console.log(arr.sort((a,b) => a - b)); // [ 1, 2, 3, 10, 111 ]

slice()

slice() 메서드는 복사를 시작할 위치와 복사를 마무리 할 위치를 인수로 받습니다. 이 때, 마무리 할 위치의 앞 인덱스까지 복사되므로 주의해야 합니다.

const arr = [1, 10, 111, 2, 3];
console.log(arr.slice(0, 4)); // [ 1, 10, 111, 2 ] -> 0 부터 4 번째가 아닌 0 ~ 3 까지.

코드 및 마무리

종합적인 코드는 아래와 같습니다.

function solution(array, commands) {
    var answer = [];
    
    for (const command of commands) {
        const [start, end, answerIdx] = command;
        answer.push(array.slice(start - 1, end).sort((a, b) => a - b)[answerIdx-1]);
    }

    return answer;
}

 

이번 문제를 통해 slice() 메서드를 사용하는 방법과 sort() 의 문제점을 알게 되었습니다. sort() 는 암묵적으로 문자열로 형변환을 시킨후에 정렬을 하기 때문에 숫자를 정렬할때는 주의해야 하고 이를 해결하기 위해서는 비교 함수를 만들어서 인수로 넣어줘야 한다는 점도 알게됬습니다.

 

이 문제는 아래의 사이트에서 풀어보실 수 있어요!

 

 

코딩테스트 연습 - K번째수

[1, 5, 2, 6, 3, 7, 4] [[2, 5, 3], [4, 4, 1], [1, 7, 3]] [5, 6, 3]

programmers.co.kr