본문 바로가기

Algorithm

프로그래머스 코딩테스트 연습 - 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입니다.

 


프로그래머스에서 복붙한 문제입니다

 

일단 주어진 배열을 쪼개서 오름차순으로 정렬 후

그 정렬에서 특정 인덱스의 값을 저장하는 문제입니다.

 

막 풀었던 효율이라고는 없어 보이는 제 코드를 보여 드리겠습니다

class Solution {
    public int[] solution(int[] array, int[][] commands) {
        int [] answer = new int[commands.length];
        
        //자를 배열의 첫번째 인덱스를 first
        //마지막 인덱스를 last
        //자른 배열의 값 중 찾아야하는 값의 인덱스 num
        int first, last, num;
        
        for(int i = 0;i < commands.length;i++)
        {
        	각 commands의 배열에 따라 값을 넣어줌
            first = commands[i][0]-1;
            last = commands[i][1]-1;
            num = commands[i][2]-1;
            
            //last와 first가 같으면 한 개의 배열만 있기 때문에 바로 값에 넣어줌
            if(last == first)
                answer[i] = array[first];
            else{
            	//문제를 풀기 위한 빈 배열 temp를 선언하고 array의 값을 copy한다
                int[] temp = new int[last-first+1];
                for(int j = 0;j < temp.length;j++)
                {
                    temp[j] = array[first+j];
                }
                
                //정렬하기 위한 중첩 반복문
                for(int j = 0;j < temp.length;j++)
                {
                    for(int k = j+1;k < temp.length;k++)
                    {
                        int buffer;
                        if(temp[j] > temp[k]){
                            buffer = temp[j];
                            temp[j] = temp[k];
                            temp[k] = buffer;
                        }
                    }
                }
                answer[i] = temp[num];
            }
        }
        return answer;
    }
}

이게 제가 풀어서 정답으로 나왔던 코드입니다

간단한 작업들이 나열됐지만 솔직히 저는 만족스럽지 못합니다

JAVA를 공부하고 있지만 이런 기본적인 것만 알아서 더 좋은 개발자가 되지 못한다고 생각합니다

제가 한 풀이에 대한 결과입니다

테스트 1 통과 (0.01ms, 52.9MB)
테스트 2 통과 (0.03ms, 52.1MB)
테스트 3 통과 (0.01ms, 51.5MB)
테스트 4 통과 (0.02ms, 54.4MB)
테스트 5 통과 (0.04ms, 52.3MB)
테스트 6 통과 (0.02ms, 53MB)
테스트 7 통과 (0.02ms, 51.5MB)

그래서 다른 사람이 푼 코드를 보니

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;
    }
}

엄청 깔끔합니다

솔직히 보고 '아 이렇게도 가능했지!!'라는 생각을 했는데

얼마나 코딩을 안 했으면 이렇게 되는 건지...ㅎㅎㅎ

조금 현타가 오긴 왔네요

테스트 1 통과 (0.47ms, 52.2MB)
테스트 2 통과 (0.43ms, 52MB)
테스트 3 통과 (0.45ms, 52.9MB)
테스트 4 통과 (0.45ms, 52.3MB)
테스트 5 통과 (0.34ms, 51.8MB)
테스트 6 통과 (0.43ms, 53MB)
테스트 7 통과 (0.47ms, 52.3MB)

위 코드에 대한 결과입니다

비교를 해보니 시간은 제가 쓴 코드가 빠르네요

라이브러리를 쓰지 않고 모든 로직을 제가 짰기 때문에 그런가 봅니다

하지만 코드의 품질을 결정하는 요소 중 가독성은

다른 개발자들과의 커뮤니케이션을 위해 중요합니다

 

그래서 저는 깔끔한 코드가 더 품질이 높다고 생각해요

 

여러분들은 이런 좋은 코드들을 보고 많이 배우시기 바랍니다

라이브러리 목록을 쭉 한 번 봐야겠네요