백준 : 힙 정렬2

김아무개·2023년 3월 22일
0

백준

목록 보기
5/17


이번 문제는 수도코드가 문제에 함께 나와있었어서 정말 금방 끝낼줄 알았는데...............................................................................................................................................................................................................................................................................................................................orz......................................................

내 코드

package codingtest.baekjoon;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    private static int[] heap;
    private static int n;
    private static int K;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = st.hasMoreTokens() ? Integer.parseInt(st.nextToken()) : 0;
        K = st.hasMoreTokens() ? Integer.parseInt(st.nextToken()) : 0;
        st = new StringTokenizer(br.readLine());

        heap = new int[n + 1];
        int idx = 1;
        while (st.hasMoreTokens()) {
            heap[idx++] = Integer.parseInt(st.nextToken());
        }

        try {
            heapSort(heap);
            if (K > 0)  System.out.println(-1);
        } catch(Exception e) {
            System.out.print(Arrays.toString(heap).replaceAll("[\\]\\[,]", "").substring(2));
        }
    }

    private static void heapSort(int[] A) throws Exception {
        buildMinHeap(A, n);

        for (int i = n; i >= 2; i--) {
            swap(A, 1, i);
            heapify(A, 1, i - 1);
        }
    }
    private static void swap(int[] A, int a, int b) throws Exception {
        int targetIdx = A[a];
        A[a] = A[b];
        A[b] = targetIdx;
        if (--K == 0) throw new Exception();
    }
    private static void buildMinHeap(int[] A, int n) throws Exception {
        for (int i = n / 2; i >= 1; i--) {
            heapify(A, i, n);
        }
    }
    private static void heapify(int[] A, int k, int n) throws Exception {
        int left = 2 * k;
        int right = 2 * k + 1;
        int smaller;

        if (right <= n) {
            smaller = (A[left] < A[right]) ? left : right;
        } else if (left <= n) {
            smaller = left;
        } else {
            return;
        }

        if (A[smaller] < A[k]) {
            swap(A, k, smaller);
            heapify(A, smaller, n);
        }
    }
}

보고 배운 코드

https://velog.io/@studyhard/ps-boj-24174

아무래도 이분 블로그를 즐겨찾기에 추가해놔야 할 것 같다 🤓
이분 코드를 통해
예외처리를 이용하여 원하는 부분에서 실행을 멈추고
에러가 발생한 코드를 실행한 곳에서
예외발생시에 작동될 코드를 작성하는 아이디어를 배웠다.

나는 처음에 내 코드에서 값의 교환이 일어나는 부분을 따로 함수로 분리하여 사용하지 못하고
온갖 교환이 일어나는 곳에 K 변수의 값을 체크해서 return , break 를 붙였었는데
계속 시간 초과 오류가 났었다.
그런데 이 교환이 일어나는 부분을 swap이라는 함수로 따로 분리한 뒤
swap에서 원하는 조건이 달성되면 진행을 멈추고 결과를 반환하기 위해서
예외를 발생시켜 main()으로 돌아가게 했더니
코드가 많이 깔끔해지고 시간초과 오류도 발생하지 않게 되었다.

그런데 시간초과 오류를 해결하니 84%쯤에서 계속 틀렸다고 나와서 한 30분 더 헤맸는데
원인은 결과를 출력하는 부분에서 K가 0보다 클 경우를 체크하는 조건을
try문에 작성했어야 하는걸
catch문에 작성했어서 발생한거였다.ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
정말 어이가 없네..🥸

모르는 부분도 많지만,
아직도 코드를 작성할때 꼼꼼하지 못한점이 많은 것 같다.
실수도 실력이라고 들었는데
실력을 늘리기 위해서는
특히 코딩테스트를 풀때 조급해지는 마음에 무작정 코드부터 작성하는 습관.
이것부터 얼른 고쳐야 할 것 같다.

앞으로는 코드를 작성하기 전에 꼭 메모를 하고
메모도 함께 올려야지...!!!!!!!
그러면 조금이라도 나아지겠지..????
일주일 단위로 내 코드에 어떤 변화가 생기는지도 확인해봐야겠다.
화이탱 💪

profile
Hello velog! 

0개의 댓글