1517번 버블 소트2 (Java)
Date: Updated:카테고리: baekjoon
문제 설명
N개의 수로 이루어진 수열 A[1], A[2], …, A[N]이 있다. 이 수열에 대해서 버블 소트를 수행할 때, Swap이 총 몇 번 발생하는지 알아내는 프로그램을 작성하시오.
버블 소트는 서로 인접해 있는 두 수를 바꿔가며 정렬하는 방법이다. 예를 들어 수열이 3 2 1 이었다고 하자. 이 경우에는 인접해 있는 3, 2가 바뀌어야 하므로 2 3 1 이 된다. 다음으로는 3, 1이 바뀌어야 하므로 2 1 3 이 된다. 다음에는 2, 1이 바뀌어야 하므로 1 2 3 이 된다. 그러면 더 이상 바꿔야 할 경우가 없으므로 정렬이 완료된다.
제한 조건
- 시간제한 : 1초
- 메모리제한 : 512MB
입력 설명
첫째 줄에 N(1 ≤ N ≤ 500,000)이 주어진다. 다음 줄에는 N개의 정수로 A[1], A[2], …, A[N]이 주어진다. 각각의 A[i]는 0 ≤ A[i] ≤ 1,000,000,000의 범위에 들어있다.
출력 설명
첫째 줄에 Swap 횟수를 출력한다
예제 입력 및 출력1
3
3 2 1
3
나의 풀이
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int[] arr, temp;
public static long result;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int arrLength = Integer.parseInt(br.readLine());
arr = new int[arrLength + 1];
temp = new int[arrLength + 1];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=1; i<=arrLength; i++){
arr[i] = Integer.parseInt(st.nextToken());
}
result = 0;
mergeSort(1, arrLength);
System.out.println(result);
}
public static void mergeSort(int start, int end){
if(end - start < 1) return;
int median = start + (end - start) / 2; // 중간 인덱스
mergeSort(start, median);
mergeSort(median+1, end);
for(int i=start; i<=end; i++){
temp[i] = arr[i];
}
int resultArrIdx = start; // 병합용 인덱스
int left = start;
int right = median+1;
while(left <= median && right <= end){ // 두개의 그룹(배열) 병합
if(temp[left] > temp[right]){
// 왼쪽 값이 크므로 오른쪽 값을 삽입 (오름차순)
arr[resultArrIdx] = temp[right];
result += right - resultArrIdx; // 앞으로 이동(스왑)했으므로 이동한 idx 만큼 결과에 추가
resultArrIdx++;
right++;
} else {
// 오른쪽 값이 크므로 왼쪽 값을 삽입 (오름차순)
arr[resultArrIdx] = temp[left];
resultArrIdx++;
left++;
}
}
// 왼쪽과 우측 그룹의 인덱스가 아직 남아있을 경우 전부 소진
while(left <= median){
arr[resultArrIdx] = temp[left];
left++;
resultArrIdx++;
}
while(right <= end){
arr[resultArrIdx] = temp[right];
right++;
resultArrIdx++;
}
}
}
제목은 버블 소트지만 숫자의 범위가 크므로 버블 소트로 구현시 시간초과 발생.
버블 소트의 경우, idx 1번의 이동 = swap 을 의미하므로 swap 구간을 캐치하여 이동한 idx 만큼을 저장하는 방식으로 구현해야한다.
O(nlogn) 시간복잡도를 가진 merge sort로 구현
댓글남기기