Skip to content

[백준/Java] 1517번: 버블 소트 #67

@peppermintt0504

Description

@peppermintt0504

문제 풀이
해당 문제는 최대 배열의 길이가 500,000이므로 버블소트를 진행한다면 O(N^2)로 시간 초과가 나온다. 시간 초과를 피하기 위해 버블 솔트와 같이 스왑을 하지만 시간 복잡도가 낮은 병합 정령(merge sort)로 문제를 풀었다.

병합 정렬을 이용하여 O(nlogn)으로 해결할 수 있다.

image

  • 정렬된 LeftArray와 RightArray로 나누어서 LeftArray의 길이를 count에 넣고 정렬을 시작한다.
    image

  • 이제 LeftArray의 맨 앞단의 숫자와 RightArray의 맨 앞단 숫자를 비교한다.

  • 이 과정에서 작은 숫자를 새로운 배열에 추가한다.

  • 해당 숫자가 RightArray의 숫자라면 count를 SwapCount에 추가한다.

  • 해당 숫자가 LeftArray의 숫자라면 count를 줄인다.

  • 위 그림에서는 RightArray의 1을 삽입하고, count 3을 Swapcount에 추가한다.

image

  • LeftArray 값이 작으므로 2를 넣고, LeftArray의 값이 들어가는 경우 Count를 1 줄인다.

image

  • LeftArray 값이 작으므로 3을 넣고, Count를 줄인다.

image

  • RightArray 값이 작으므로 4를 넣고, Swap에 Count를 더한다.
  • 한쪽 배열이 비어있으면 다른 배열의 값을 그냥 넣는다.

위 병합 정렬을 사용하면 시간 초과 없이 스왑 횟수를 출력할 수 있다.

풀이 코드

import java.io.*;
import java.util.*;
import java.util.Map.Entry;

public class Main {
	public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	public static StringTokenizer st;
	public static int INF = Integer.MAX_VALUE;
	
	
	static long swapCount = 0;
    static long[] sorted;
	
	public static void main(String[] args) throws IOException {
		
		int N = Integer.parseInt(br.readLine());
       
        
        sorted = new long[N];
        long[] arr = new long[N];
 
        arr = Arrays.stream(br.readLine().split(" ")).mapToLong(Long::parseLong).toArray();
 
        mergeSort(arr, 0,N-1);
	        
        System.out.println(swapCount);
	}
    static void mergeSort(long[] arr, int left, int right) {
    	if(left < right) {
    		int mid = (left + right) / 2;
    		mergeSort(arr,left,mid);
    		mergeSort(arr,mid+1,right);
    		merge(arr, left,right);
    	}
    }
 
    static void merge(long[] arr, int start, int end) {
    	int mid = (start+end) / 2;
    	int left = start;
    	int right = mid+1;
    	int index = start;
    	
    	while(left <= mid && right <= end) {
    		if(arr[left] <= arr[right]) {
    			sorted[index++] = arr[left++];
    		}else {
    			sorted[index++] = arr[right++];
    			swapCount += mid + 1 - left;
    		}
    	}
    	while(left <= mid) {
    		sorted[index++] = arr[left++];
    	}
    	while(right <= end) {
    		sorted[index++] = arr[right++];
    	}
    	for(int i = start; i <= end; i++) {
    		arr[i] = sorted[i];
    	}
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions