본문 바로가기
코딩테스트

[프로그래머스 Lv.1 / Java] K번째 수

by 지지 2022. 2. 12.

[문제]

K번째 수

배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다.

예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면

   1. array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]입니다.

   2. 1에서 나온 배열을 정렬하면 [2, 3, 5, 6]입니다.

   3. 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입니다.


[풀이]

import java.util.Arrays;

class Solution {
    public int[] solution(int[] array, int[][] commands) {
    	//k번째 수를 담아줄 배열 생성
        int[] answer = new int[commands.length];

        for(int i = 0; i<commands.length; i++){
            //array를 원하는 범위만큼 복사하는 새로운 배열 생성
            int[] array2 = Arrays.copyOfRange(array, commands[i][0]-1, commands[i][1]);
			
            //정렬
            Arrays.sort(array2);
            //k번째 수 담기
            answer[i] = array2[commands[i][2]-1];
        }

        return answer;
    }
}

1. k번째 수를 담아줄 배열을 생성한다(정답이 될 배열). 이 때 길이는 2차원 배열인 commads의 길이로 맞춰준다. 

   -why? 어차피 정답 배열의 길이는 문제에서 제시한 commands배열이 길이가 되기 때문이다.

2. commands의 길이만큼 for문을 돌린다.

3. for문 안에서는 array를 원하는 범위만큼 복사하는 새로운 배열 array2를 만들어준다.

4. Arrays.copyOfRange메서드를 활용하여 array배열을 원하는 길이만큼 자른다.

   - Arrays.copyOfRanges는 매개변수로 (복사할 배열, 복사 시작 숫자, 복사 끝 숫자)를 받아서 어떤 배열을

     어디서부터 어디까지 복사할 건지 정해서 배열을 복사할 수 있다!

   - 예를 들어, 위 코드는 array라는 배열의 commands[i][1]-1부터 commands[i][1]까지 복사한다는 뜻이다.

   - 두 번째 매개변수는 복사를 시작할 범위를 정하는데, 내가 지정해준 숫자(순서)의 다음 원소부터 복사가 시작된다.

   - 즉, (array, 2, 5)를 매개변수로 넣어준다면 2의 다음인 세 번째 부터 복사가 시작된다는 것이다!!!!!

   - 예를 들어 commands[0][0]이 2로 제공됐다면 두 번째 숫자부터 자르라는 의미이다. 그렇다면 두 번째 매개변수를

     1로 해주어야 1의 다음은 두 번째 부터 복사가 시작된다! 그렇기에 -1을 해준 것이다!

   - Arrays.copyOfRanges는 원하는 범위 만큼 복사를 해서 새로운 배열을 만들어 주지만, 배열처럼 번호를 0,1,2 ... 로

     생각하지 말고 순서인 첫 번째 값, 두 번째 값 이렇게 생각을 해야할 것 같다!

5. sort메서드를 이용한 배열 오름차순 정렬

6. answer배열에 k번째 수를 담아준다. (for문이 다 돌면 정답이 될 answer 반환)

   - 이 때도 k(commands[i][2])가 3이 제공 되었다면, 배열에서는 인덱스번호로 [2]의 원소를 넣어주어야 하기 때문에 

     -1을 해주어야 한다.


[느낀점]

Arrays.copyOfRange를 학원 수업시간에 한 번 써본 것 빼고는 써본적이 없어서 조금 헤멧다.

사실 내 힘으로는 풀지 못했고, 다른 사람들의 풀이를 먼저 보고 풀었는데 Arrays.copyOfRange의 범위가 블로그마다 조금씩 다르게 적혀있어서 이게 맞나? 저게 맞나?하다가 푸는데 더 늦어진 것 같다.

이렇게 많은 정보에 헷갈릴 때는 자바 기본서가 옆에 있었다면 기본서를 참고했으면 좋았을텐데... 집이 아닌 곳에서 푼것이 조금 아쉽다!

그래도 복사 범위를 직접 실험하고 공부하면서 메서드를 더 잘 이해할 수 있게 된 것 같다.

그리고 풀이에서 이 메서드를 설명하면서 느낀점은, 배열을 설명할 때의 개념을 내가 헷갈려하고 있다는 것을 알게됐다.

이 부분에서 인덱스라고 쓰는 게 맞나? 원소라고 써야하나? 이렇게 계속 의문을 가지면서 작성했다.

내일은 배열 기본을 다시 복습하고 와야겠다!

댓글