ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스] K번째 수 - 정렬
    알고리즘/문제풀기 2019. 4. 20. 12:33

    새로운 배열에 부분 배열을 저장하고 그 배열을 다시 정렬하는 식으로 풀기 시작했다.

    처음엔 쉬운 문제라고 생각했는데 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() 메소드는 첫 번째 매개변수로 복사의 대상이 될 원본 배열을 전달받습니다.

    두 번째 매개변수로는 원본 배열에서 복사할 시작 인덱스를 전달받고, 세 번째 매개변수로는 마지막으로 복사될 배열 요소의 바로 다음 인덱스를 전달받습니다.

    즉, 세 번째 매개변수로 전달된 인덱스 바로 전까지의 배열 요소까지만 복사됩니다.

    그리고 원본 배열과 같은 타입의 복사된 새로운 배열을 반환합니다.

     

    참고 : http://tcpschool.com/java/java_api_arrays

    댓글

Designed by Tistory.