티스토리 뷰
문제
버블정렬에 관한 이야기 진행
- 인접해 있는 두 수를 swap하며 정렬 진행
- (배열 크기 + 배열 제공)
- 버블정렬을 진행할 때, swap하는 횟수를 구하는 프로그램을 작성하시오
시간 제한 : 1초
버블정렬 시간복잡도 : O(N^2)
배열 범위 : 1<= N <= 500,000
문제분석
버블정렬로 진행할 시, 시간 초과로 인해 swap을 구하더라도 문제에 제시되어있는 시간을 지킬 수가 없다.
따라서, O(NlogN)을 가진 정렬하는 방식을 채택해야함
(병합 정렬 선택)
- 병합정렬 선택시 주의할점)
- 병합정렬이 swap되는 횟수를 구하는 것이 아닌, 버블정렬이 swap되는 횟수를 구해야함
- 인덱스 위치의 변화를 통한 , 버블정렬의 swap 횟수를 구해야함
- 예시
- 2를 이동시에 5와 6을 뒤로 보내야한다 ( 버블정렬 시 swap되는 항목 )
- (2,5) , (2,6) 스왑이 일어남
- 따라서, 그룹2에서 이동한 인덱스 만큼 버블정렬에서는 swap이 일어남 (아이디어)
- 2를 이동시에 5와 6을 뒤로 보내야한다 ( 버블정렬 시 swap되는 항목 )
그룹1 | 그룹2 |
||||
1 | 5 | 6 | 2 | 3 | 4 |
(그룹 1 + 그룹 2 정렬) | |||||
1 | 2 | 3 | 4 | 5 | 6 |
(인덱스 +2 이동) | (인덱스 + 2이동) | (인덱스 + 2이동) |
슈도코드
N (정렬 개수)
arr (정렬 배열)
tmp (병합 정렬시 사용되는 배열)
mergeSort (병합정렬)
결과 출력
//병합정렬 코드
병합정렬 (start , end)
start (시작점)
end (끝점)
middle (중간점)
병합정렬 (start, middle);
병합정렬 (middle+1, end);
// end로 지정한 이유는 ( start ~ middle / middle+1 ~end 2개의 그룹으로 나누기 위해)
for( s ~ e ){
tmp 배열 저장하기
}
index1 = 앞쪽 그룹
index2 = 뒤쪽 그룹
while(index1 <= 중간점 && index2 <= end ){
뒤쪽데이터값이 더작아 선택될때,
swap이 일어났다고 가정하고, 현재 남아있는 앞쪽 데이터 개수만큼 결과값을 더함
}
반복문 끝난 후 남아있는 데이터 정리
}
구현하기
- 병합정렬 구현하기
- "result = result + group2_index - sortIndex" 이번 문제의 해결 포인트
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class App {
public static Long result = 0L;
public static void main(String[] args) throws Exception {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int size = Integer.parseInt(bf.readLine());
int[] arr = new int[size];
int[] tmp = new int[size];
StringTokenizer st = new StringTokenizer(bf.readLine());
int i = 0;
while(st.hasMoreTokens()){
arr[i++] = Integer.parseInt(st.nextToken());
}
mergeSort(arr,tmp,0, size-1);
System.out.println(result);
}
private static void mergeSort(int[] arr,int[] tmp, int startIndex, int endIndex){
if (startIndex >= endIndex){
return;
}
int middleIndex = startIndex + (endIndex - startIndex)/2;
mergeSort(arr, tmp, startIndex, middleIndex);
mergeSort(arr, tmp, middleIndex + 1, endIndex);
for (int i = startIndex; i <= endIndex; i++){
tmp[i] = arr[i];
}
int sortIndex = startIndex;
int group1_index = startIndex;
int group2_index = middleIndex+1;
while(group1_index <= middleIndex && group2_index <= endIndex){
if(tmp[group1_index] > tmp[group2_index]){ // 정렬되지 않은 곳은 2개의 그룹을 섞을때만 (각각의 그룹은 정렬이 되어있다)
arr[sortIndex] = tmp[group2_index];
result = result + group2_index - sortIndex;
sortIndex++;
group2_index++;
}else{
arr[sortIndex] = tmp[group1_index];
sortIndex++;
group1_index++;
}
}
while(group1_index <= middleIndex){
arr[sortIndex] = tmp[group1_index];
sortIndex++;
group1_index++;
}
while(group2_index <= endIndex){
arr[sortIndex] = tmp[group2_index];
sortIndex++;
group2_index++;
}
}
}
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 게시판 프로젝트
- 코딩테스트
- 클래스
- 버블정렬
- 예외처리
- 깊이우선탐색
- JSON
- 타입변환
- stack
- Spring
- HTML5
- 오블완
- 우선순위 큐
- Thymeleaf
- 이진탐색
- bean
- 게시판
- Java
- BFS
- SQL
- db
- 알고리즘
- 티스토리챌린지
- 검증
- 포트폴리오
- JDBC
- 백준
- 정렬
- DFS
- 기술면접
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함