[프로그래머스] K번째 수 - 정렬
새로운 배열에 부분 배열을 저장하고 그 배열을 다시 정렬하는 식으로 풀기 시작했다.
처음엔 쉬운 문제라고 생각했는데 commands배열안에서 부분 시작과 끝을 찾아야한다고 생각하니까 조금 복잡했다.
※ 첫 번째 코드
아래의 코드처럼 temp라는 배열을 반복해서 다시 저장하는 식으로 코드를 짰다.
public static int[] solution(int[] array, int[][] commands) {
int[] answer = {};
int[] temp = {};
for(int j=0; j<commands.length; j++) {
int start = commands[j][0]-1; //-1씩 해준 이유는 배열은 0부터 시작해서 index값이 1씩 작기 때문에
int end = commands[j][1]-1;
int pick = commands[j][2]-1;
for(int k=start; k<=end; k++) {
temp[k] = array[k];
}
Arrays.sort(temp);
answer[j] = temp[pick]; //정렬된 temp에서 pick인덱스 값을 answer배열에 저장
}
return answer;
}
java.lang.ArrayIndexOutOfBoundsException 오류가 발생했다.
검색을 해보니 배열에 해당하지 않는 인덱스에 접근하려고 시도했기 때문에 발생한 오류라고 했다.
코드를 다시 살펴보니 배열의 크기를 할당하지 않아서 생긴 오류라고 생각했다.
※ 두 번째 코드
아래 주석 처럼 배열마다 각 크기를 할당 해주었다.
answer배열은 항상 commands배열의 크기와 같을 것이라서 commands배열의 크기를 할당해주었고,
temp배열은 크기가 각 array배열에서 잘라낼 배열의 크기여서 계속 크기가 바뀌게 된다.
그래서 temp의 크기는 end-start+1이 되어야한다.
public static int[] solution(int[] array, int[][] commands) {
int clength = commands.length; //commands배열의 크기를 저장
int[] answer = new int[clength]; //answer배열의 크기는 항상 commands크기와 같다
for(int j=0; j<clength; j++) { //commands배열의 크기만큼 반복한다
int start = commands[j][0]-1;
int end = commands[j][1]-1;
int pick = commands[j][2]-1;
int size = end-start+1; //temp배열의 크기를 할당하기 위한 size변수
int temp[] = new int[size]; //temp배열의 크기는 부분배열의 크기어야 하니까 end-start+1이 된다.
int i=0; //temp에 순서대로 넣기 위한 변수
for(int k=start; k<=end; k++) {
temp[i] = array[k]; //temp에 순서대로 array에서 잘라낸 배열을 저장함
i++;
}
Arrays.sort(temp); //temp 배열을 정렬하는 코드
answer[j] = temp[pick]; //정렬된 temp배열에서 pick인덱스를 answer에 저장
}
return answer;
}
위에 코드처럼 temp와 answer의 배열을 할당해주었더니 오류는 사라졌지만 결과가 제대로 나오지 않았다.
디버깅을 해보니까 Arrays.sort(temp); 부분에서 오류가 났다.
분명 이클립스에서 실행했을때는 이상한 결과 값이 나왔는데, 프로그래머스에서 똑같은 코드를 돌려봤는데 결과는 통과였다!
이클립스에서는 왜 안돌아갔는지는 알수없었다.. 프로그래머스에서는 왜 통과가 된거지??
★다른 사람 풀이
이 코드는 너무너무 간단하게 풀 수 있는 방법이 있어서 가져왔다!
import java.util.Arrays;
class Solution {
public int[] solution(int[] array, int[][] commands) {
int[] answer = new int[commands.length];
for(int i=0; i<commands.length; i++){
int[] temp = Arrays.copyOfRange(array, commands[i][0]-1, commands[i][1]);
Arrays.sort(temp);
answer[i] = temp[commands[i][2]-1];
}
return answer;
}
}
나는 Arrays.copyOfRange라는 함수를 몰랐는데, 다른 사람의 코드를 보고 공부 할 수 있는 것이 좋은 것 같다.
copyOfRange 함수는 Arrays클래스에 있는 함수이다.
copyOfRange() 메소드는 전달받은 배열의 특정 범위에 해당하는 요소만을 새로운 배열로 복사하여 반환한다.
즉, 이 문제에서 원하는 결과와 완벽하게 일치하는 함수였다..
copyOfRange() 메소드는 첫 번째 매개변수로 복사의 대상이 될 원본 배열을 전달받습니다.
두 번째 매개변수로는 원본 배열에서 복사할 시작 인덱스를 전달받고, 세 번째 매개변수로는 마지막으로 복사될 배열 요소의 바로 다음 인덱스를 전달받습니다.
즉, 세 번째 매개변수로 전달된 인덱스 바로 전까지의 배열 요소까지만 복사됩니다.
그리고 원본 배열과 같은 타입의 복사된 새로운 배열을 반환합니다.