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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions