Pepperminttt
Pepperminttt's Dev
Pepperminttt
전체 방문자
오늘
어제
  • devInfo (86)
    • forBeingGoodDeveloper (2)
    • React (2)
      • LostArk Open API (1)
    • algorithm (58)
      • problems (44)
      • theory (14)
    • computerScience (8)
      • network (8)
    • javaScript (8)
    • Java (4)
    • web (2)
      • webApplication (2)
    • etc. (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • C++
  • solved.ac
  • 탐욕법
  • 백준
  • greedy
  • bfs문제
  • 프로그래머스
  • BFS
  • Network
  • node.js
  • Java
  • 그래프
  • dfs
  • DP
  • JavaScript
  • 탐욕법 문제
  • 벨만-포드
  • dfs문제
  • 알고리즘
  • DP문제

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Pepperminttt

Pepperminttt's Dev

[백준/Java] 1517번: 버블 소트(병합 정렬[Merge Sort])
algorithm/problems

[백준/Java] 1517번: 버블 소트(병합 정렬[Merge Sort])

2023. 8. 31. 10:10

 

문제

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 이 된다. 그러면 더 이상 바꿔야 할 경우가 없으므로 정렬이 완료된다.

입력

첫째 줄에 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

예제 출력 1

3

문제 풀이

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

 

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

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

  • 이제 LeftArray의 맨 앞단의 숫자와 RightArray의 맨 앞단 숫자를 비교한다.
  • 이 과정에서 작은 숫자를 새로운 배열에 추가한다.
  • 해당 숫자가 RightArray의 숫자라면 count를 SwapCount에 추가한다. 
  • 해당 숫자가 LeftArray의 숫자라면 count를 줄인다. 
  • 위 그림에서는 RightArray의 1을 삽입하고, count 3을 Swapcount에 추가한다.

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

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

  • 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];
    	}
    }
}

'algorithm > problems' 카테고리의 다른 글

[백준/Java] 17472: 다리 만들기 2  (0) 2023.09.20
[백준 / Java] 2110번: 공유기 설치  (0) 2023.09.19
[백준 / Java] 1194번: 달이 차오른다, 가자.  (0) 2023.08.25
[백준 / Java] 2473번 : 세 용액  (0) 2023.08.22
[백준 / Java] 2263번 : 트리의 순회  (0) 2023.08.21
    'algorithm/problems' 카테고리의 다른 글
    • [백준/Java] 17472: 다리 만들기 2
    • [백준 / Java] 2110번: 공유기 설치
    • [백준 / Java] 1194번: 달이 차오른다, 가자.
    • [백준 / Java] 2473번 : 세 용액
    Pepperminttt
    Pepperminttt
    HTML, JavaScript, Python 등 Computer language TIL

    티스토리툴바