📌Zero-base
백준 24174번 힙 정렬2 제로베이스 자료구조 마지막 주제 : Heap
구 일
2024. 4. 20. 19:25
728x90
반응형
자료구조 1 Page 노트 정리 마지막 주제 : Heap
백준 24174번 알고리즘 수업 - 힙 정렬 2 문제 풀이
기존 문제에 주어진 의사코드를 그대로 구현 후 원소 교환을 위한 swap() 메소드를 추가했고, 코드 구현 후 문제 제출했는데 제한 시간 1초를 넘겨 계속 실패를 반복했다.
제한 시간 1초를 위해서 예외를 강제로 발생시키고, 배열 출력 시 미리 StringBuilder에 배열을 담아서 그대로 출력하는 방법으로 제한 시간 문제를 해결했다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static int cnt = 0; // 교환 횟수
static int K; // 입력 K 값
static boolean isSuccess = false; // 출력 성공 체크를 위한 값
static StringBuilder sb = new StringBuilder(); // 배열 출력을 위한 StringBuilder
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 배열의 크기 A와 교환 횟수 K 값 설정
int[] inputAK = Arrays
.stream(br.readLine().split(" ")) // 공백을 기준으로 문자열 분리
.mapToInt(Integer::parseInt) // int형으로 형변환
.toArray(); // 배열에 담기
int A = inputAK[0];
K = inputAK[1];
// 입력 받은 배열
StringTokenizer st = new StringTokenizer(br.readLine());
int[] array = new int[A + 1]; // 루트 값을 index 1번으로 하기 위해서 length를 1 늘려준다
for (int i = 1; i < array.length; i++) {
array[i] = Integer.parseInt(st.nextToken());
}
try {
heapSort(array);
} catch (RuntimeException e) {
System.out.println(sb); // 시간 제한 1초로 K와 cnt가 같을 때 배열 출력
}
if (!isSuccess) {
System.out.println(-1); // 출력 실패 시 -1 출력
}
br.close();
}
/**
* 원소 교환
* @param array
* @param a
* @param b
*/
static void swap(int[] array, int a, int b) {
cnt++;
int tmp = array[a];
array[a] = array[b];
array[b] = tmp;
if (cnt == K) {
isSuccess = true;
for (int i = 1; i < array.length; i++) {
sb.append(array[i]).append(" ");
}
throw new RuntimeException(); // 강제로 예외 발생
}
}
/**
* 정렬
* @param array
*/
static void heapSort(int[] array) {
buildMinHeap(array, array.length - 1);
for (int i = array.length - 1; i > 1; i--) {
swap(array, 1, i);
heapify(array, 1, i - 1);
}
}
/**
* 최소 힙 생성
* @param array
* @param A
*/
static void buildMinHeap(int[] array, int A) {
for (int i = A / 2; i >= 1; i--) {
heapify(array, i, A);
}
}
/**
* array[K]를 루트로 하는 트리를 최소 힙 성질을 만족하도록 수정
* array[K]의 두 자식을 루트로 하는 서브 트리는 최소 힙 성질을 만족하고 있다.
* A는 배열 Array의 전체 크기이며 최대 인덱스를 나타낸다.
* @param array
* @param K
* @param A
*/
static void heapify(int[] array, int K, int A) {
int left = K * 2;
int right = K * 2 + 1;
int smaller;
if (right <= A) {
if (array[left] < array[right]) {
smaller = left;
} else {
smaller = right;
}
} else if (left <= A) {
smaller = left;
} else {
return;
}
// 최소 힙 성질을 만족하지 못하는 경우 재귀적으로 수정한다.
if (array[smaller] < array[K]) {
swap(array, K, smaller);
heapify(array, smaller, A);
}
}
}
728x90
반응형