ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #AIL_23.10.26 // Programmers_정렬_K번째 수
    AIL( Algorithm I Learned) 2023. 10. 26. 20:20

    ## AIL_정렬_K번째 수

    문제 설명
    배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다.예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]입니다.1에서 나온 배열을 정렬하면 [2, 3, 5, 6]입니다.2에서 나온 배열의 3번째 숫자는 5입니다.배열 array, [i, j, k]를 원소로 가진 2차원 배열 commands가 매개변수로 주어질 때, commands의 모든 원소에 대해 앞서 설명한 연산을 적용했을 때 나온 결과를 배열에 담아 return 하도록 solution 함수를 작성해주세요.

    제한사항
    - array의 길이는 1 이상 100 이하입니다.
    - array의 각 원소는 1 이상 100 이하입니다.
    - commands의 길이는 1 이상 50 이하입니다.
    - commands의 각 원소는 길이가 3입니다.

    입출력 예
    array commands return
    [1, 5, 2, 6, 3, 7, 4] [[2, 5, 3], [4, 4, 1], [1, 7, 3]] [5, 6, 3]

    입출력 예 설명
    [1, 5, 2, 6, 3, 7, 4]를 2번째부터 5번째까지 자른 후 정렬합니다. [2, 3, 5, 6]의 세 번째 숫자는 5입니다.[1, 5, 2, 6, 3, 7, 4]를 4번째부터 4번째까지 자른 후 정렬합니다. [6]의 첫 번째 숫자는 6입니다.[1, 5, 2, 6, 3, 7, 4]를 1번째부터 7번째까지 자릅니다. [1, 2, 3, 4, 5, 6, 7]의 세 번째 숫자는 3입니다.

    ## solution.JavaScript

    1. 문제의 접근 방식

    주어진 배열을 일련의 명령에 따라 자르고 결과를 반환하는 문제입니다. `array`와 명령들을 담고 있는 2차원 배열 `commands`가 주어지며, 각 명령은 `[i, j, k]`형식으로 주어집니다. 이때 `i`번째부터 `j`번재까지의 부분배열을 만들고 이 부분배열을 정렬한 후, `k`번째 원소을 찾아야합니다. 

     

    1) commands 배열을 순회하면서 각 명령을 처리합니다.

     

    2) 현재 명령을 나타내는 [i, j, k] 배열을 가져옵니다.

     

    3) i-1부터 j까지의 부분배열을 array에서 슬라이스합니다.

    (i-1을 하는 이유는 배열의 인덱스가 0부터 시작하기 때문입니다.)

     

    4)슬라이싱한 부분배열을 정렬합니다. 이때, JavaScript의 sort 메서드를 사용하며, 숫자를 오름차순으로 정렬하기 위해 비교 함수를 제공합니다.

     

    5)정렬된 부분배열에서 k-1번째 원소를 찾아내서 결과 배열에 추가합니다.

     


    2. 문제풀이

    function solution(array, commands) {
        const answers = [];
        
        // commands 배열을 순회하면서 각 명령을 처리합니다.
        for (let command of commands) {
            // 현재 명령을 나타내는 [i, j, k] 배열을 가져옵니다.
            const [i, j, k] = command;
            
            // i-1부터 j까지의 부분배열을 array에서 슬라이스합니다. (인덱스가 0부터 시작하므로 i-1을 사용)
            const slicedArray = array.slice(i-1, j);
            
            // 슬라이싱한 부분배열을 정렬합니다.
            // 숫자를 오름차순으로 정렬하기 위해 비교 함수를 제공합니다.
            slicedArray.sort((a, b) => a - b);
            
            // 정렬된 부분배열에서 k-1번째 원소를 찾아내서 결과 배열에 추가합니다.
            answers.push(slicedArray[k-1]);
        }
        
        // 결과 배열을 반환합니다.
        return answers;
    }

    - 첫 번째 명령 [2, 5, 3]에 대해, array에서 2번째부터 5번째까지의 부분배열 [5, 2, 6, 3]을 만들고 정렬하여 [2, 3, 5, 6]을 얻고, 세 번째 숫자인 5를 결과 배열에 추가합니다.

     

    - 두 번째 명령 [4, 4, 1]에 대해, 4번째부터 4번째까지의 부분배열 [6]을 만들고 정렬하여 [6]을 얻고, 첫 번째 숫자인 6을 결과 배열에 추가합니다.

     

    - 세 번째 명령 [1, 7, 3]에 대해, 1번째부터 7번째까지의 부분배열 [1, 2, 3, 4, 5, 6, 7]을 만들고 정렬하여 [1, 2, 3, 4, 5, 6, 7]을 얻고, 세 번째 숫자인 3을 결과 배열에 추가합니다.

     

    따라서, 함수는 [5, 6, 3]을 반환하게 됩니다.


    3. 다른사람의 문제풀이 및 접근방식 분석

    function solution(array, commands) {
        return commands.map(i => { // 1. commands 배열을 순회하며 각 명령에 대한 처리를 수행
    
            // 현재 명령을 나타내는 배열 i를 가져옵니다. i는 [i, j, k] 형식입니다.
            // i[0]은 시작 인덱스, i[1]은 종료 인덱스를 나타냅니다.
            // array를 슬라이스하여 i[0]에서 i[1]까지의 부분배열을 생성합니다.
            let slicedArray = array.slice(i[0] - 1, i[1]);
    
            // 슬라이싱한 부분배열을 sort 메서드를 사용하여 오름차순으로 정렬합니다.
            slicedArray.sort((a, b) => a - b);
    
            // 정렬된 부분배열에서 i[2]에 해당하는 인덱스의 값을 반환합니다.
            // 이 값은 주어진 명령에 따라 선택된 숫자입니다.
            return slicedArray[i[2] - 1];
        });
    }

    - 첫 번째 명령 [2, 5, 3]에 대해, [2, 3, 5, 6]의 세 번째 숫자는 5이며, 이 값이 결과 배열에 추가됩니다.

     

    - 두 번째 명령 [4, 4, 1]에 대해, [6]의 첫 번째 숫자는 6이며, 이 값이 결과 배열에 추가됩니다.

     

    - 세 번째 명령 [1, 7, 3]에 대해, [1, 2, 3, 4, 5, 6, 7]의 세 번째 숫자는 3이며, 이 값이 결과 배열에 추가됩니다.

    따라서, 함수는 [5, 6, 3]을 반환하게 됩니다.


    5. 두 방식의 장단점

    1) 첫번째 방식 

    • -  for...of 루프를 사용하여 명령을 순회합니다.
    • -  commands 배열의 각 명령을 배열 비구조화 할당을 사용하여 더 명확하게 처리합니다.
    • -  코드가 명시적이며 각 단계가 명확하게 표현됩니다.

    장점_//

    • - 코드의 가독성이 높습니다. 명령을 처리하는 각 단계가 분명하게 나눠져 있어 이해하기 쉽습니다.
    • - 배열 비구조화 할당을 통해 각 명령을 더 명확하게 사용할 수 있습니다.

    단점 _//

    • - 코드가 상대적으로 길어질 수 있으며 반복적인 구조를 가지고 있어 코드 양이 더 많습니다.

     

    2) 두 번째 방식:.

    • map 함수를 사용하면 루프를 직접 작성하지 않아도 되므로 코드가 더 간결합니다.
    • 중복 코드가 감소하며, 명령을 처리하는 각 부분이 하나의 map 함수 내에서 이루어지므로 코드 양이 줄어듭니다.
    • 코드가 간결하고 구조적으로 단순하므로 나중에 발생하는 유지보수 작업도 더 쉽게 처리할 수 있습니다.

    장점_//

    • 코드가 간결하고 짧아 가독성이 높습니다. map 함수를 사용하면 루프를 직접 작성하지 않아도 됩니다.
    • 루프와 명령 처리를 묶어 간결한 표현이 가능합니다.

    단점_//

    • 명령을 처리하는 각 단계가 코드 내에서 명확하게 나눠져 있지 않아, 처음에는 이 코드를 이해하는데 노력이 필요할 수 있습니다.

    결론: map 함수를 사용하는 방식 (두 번째 방식)을 사용하자!

     

Designed by Tistory.