ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로그래머스 스킬체크 레벨2
    Algorithm 2022. 5. 8. 01:16

    저번에 작성했던 레벨1 후기에 이어, 레벨2를 작성한다.

     

    사실 통과는 했지만 조금 찜찜한게,

    저번에 도전해봤을 땐 너무 어려운 문제들이 나와서 아직 때가 아니군 하면서 조용히 뒤로가기 버튼을 눌렀는데, 오늘 다시 도전했을 땐 아는 문제들이 나왔다.

     

    항상 느끼는건데 프로그래머스는 같은 레벨이라도 문제의 난이도 차이가 좀 많이 나는 것 같다..

    제한시간은 한시간이었는데, 풀만하다 생각했던 문제들이 나왔음에도 불구하고 거의 꽉채워서 제출했다.😅

     


    1. 가장 큰 수

     

     

    가장 큰 수 문제가 나왔다.

    정수를 문자열로 변환해서 사전 내림차순으로 정렬하면 되는 문제.

    단, 그냥 정렬만 하면 입출력#2에서 3, 30과 같은 수가 들어왔을 때 원하는 값은 330이 나와야 하는데 303으로 정렬해버린다.

    때문에 sort메소드를 사용할 때 comparator 매개변수를 사용해서 문자열을 두개씩 묶어 비교해야 한다.

    마지막으로, 모두 0 이 들어왔을 때 문자열 특성상 "000"과 같이 출력되는 것을 방지하기 위해 첫번째 원소가 0이면 바로 "0"을 리턴한다.

     

    전체 코드는 다음과 같다.

     

    import java.util.Arrays;
    
    class Solution {
        public String solution(int[] numbers) {
            String answer = "";
    
            String[] numSet = new String[numbers.length];
    
            for(int i=0; i<numbers.length; i++) {
    
                numSet[i] = Integer.toString(numbers[i]);
            } // for
    
            // 30, 3과 같은 숫자가 들어올 때 303이 되는 것을 방지
            // 문자열 두개씩 묶어서 비교한다.
            Arrays.sort(numSet, (o1, o2) -> (o2+o1).compareTo(o1+o2));
    
            if(numSet[0].equals("0")) {
                return "0";
            }
    
            for(String str : numSet) {
                answer += str;
            } // for
    
            return answer;
        } // solution
    } // end class

     


    2. 행렬 테두리 회전하기

     

    문제가.....너무 길다.

    전체 문제는 이곳에서(https://programmers.co.kr/learn/courses/30/lessons/77485) 확인할 수 있다.

     

    처음 코테공부를 시작할 때 이런문제만 보면 울렁거리고 대체 어떻게 푸나.. 싶었는데 이 문제는 그래도 풀만하다.

    (물론 복잡해지면 손도 못대는건 여전함)

     

    시작 행/열, 끝 행/열이 주어지면 시계방향으로 배열을 한칸씩 회전하고, 그 중 최솟값을 answer에 담으면 된다.

     

    이 문제가 그래도 풀만한 이유는 테두리만 회전하기 때문에 내부는 신경쓰지 않아도 되고, 주어진 이차원 배열의 요소가 인덱스라서 접근이 쉽기 때문이다.

     

    1차원 배열에서 값을 바꾸거나 이동할 때,

    초기값을 임시변수 tmp에 저장해두고 변경이 끝나면 저장해둔 초기값을 다시 배열에 대입하는 방식은 누구나 경험해봤을 것이다.

    이 문제는 이것의 업그레이드 버전이다.

    배열의 회전을 한줄 씩 이동한다고 생각했을 때, 한 쿼리당 4줄씩 이동한다고 생각하면 된다.(가로/세로)

     

    각각의 줄을 1차원 배열로 생각하고 접근하니 이해가 잘 됐다.

     

    전체 코드는 다음과 같다.

     

    class Solution {
    
        static int[][] board;
    
        public int[] solution(int rows, int columns, int[][] queries) {
            int[] answer = new int[queries.length];
    
            board = new int[rows][columns];
    
            // 배열 초기화
            int k = 0;
            for(int i=0; i<rows; i++) {
                for(int j=0; j<columns; j++) {
                    board[i][j] = ++k;
                } // for
            } // for
    
            // 회전
            for(int i=0; i<queries.length; i++) {
                int min = rotate(queries[i]);
    
                answer[i] = min;
            } // for
    
            return answer;
        } // solution
    
        private static int rotate(int[] query) {
    
            // 쿼리가 1부터 시작하기 때문에 1을 빼줌
            int startR = query[0] - 1;
            int startC = query[1] - 1;
            int endR = query[2] - 1;
            int endC = query[3] - 1;
    
            // 자리변경을 위해 임시변수 tmp에 시작넘버 저장
            int tmp = board[startR][startC];
            // 초기 min값 세팅
            int min = tmp;
    
            // 빈 공간을 차례대로 메꾸는 개념
            // 1. 시작행 중심 행 이동
            for(int i=startR; i<endR; i++) {
                board[i][startC] = board[i+1][startC];
    
                if(min > board[i][startC]) min = board[i][startC];
            } // for
    
            // 2. 마지막열 중심 열 이동
            for(int i=startC; i<endC; i++) {
                board[endR][i] = board[endR][i+1];
    
                if(min > board[endR][i]) min = board[endR][i];
            } // for
    
            // 3. 마지막행 중심 행 이동
            for(int i=endR; i>startR; i--) {
                board[i][endC] = board[i-1][endC];
    
                if(min > board[i][endC]) min = board[i][endC];
            } // for
    
            // 4. 마지막열 중심 열 이동
            for(int i=endC; i>startC; i--) {
                board[startR][i] = board[startR][i-1];
    
                if(min > board[startR][i]) min = board[startR][i];
            } // for
    
            // 5. 회전이 끝난 위치에 저장해뒀던 초기값 대입
            board[startR][startC + 1] = tmp;
    
            return min;
        } // rotate
    } // end class

     

    'Algorithm' 카테고리의 다른 글

    [백준] 8979 올림픽 - 자바(Java)  (1) 2022.08.03
    프로그래머스 스킬체크 레벨1 풀어보기  (0) 2022.04.10

    댓글

Designed by Tistory.