ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [퀵 정렬] 백준 11004번
    책/DoIt 알고리즘 코딩테스트 2024. 11. 12. 00:02

    문제

    - Array를 오름차순 정렬했을 때 앞에서부터 K번째 있는 수를 구하는 프로그램을 작성하시오
    - 데이터 개수 ( 1 <= N <= 5,000,000 )
    - K번째 수 ( 1 <= K <= N)

     

    문제 분석

    시간 제한 2초 : 2억번 연산 내에 구현
    (NlogN 일경우, 시간제한에 있어서는 통과할 시간복잡도이다)
    - 오름차순 정렬이 필요하므로, 퀵정렬을 이용한 풀이를 진행
    • pivot 정하는 방법
      • pivot == k : k 번째 수를 찾은 것이므로 알고리즘을 종료
      • pivot > k : pivot의 왼쪽 부분에 K가 있으므로 왼쪽 (S ~ pivot -1) 만 정렬을 수행한다
      • pivot < k : pivot의 오른쪽 부분에 K가 있으므로 오른쪽(pivot -1 -E)만 정렬을 수행한다
    • 퀵정렬은 pivot이 지정되있는 곳이 정렬된 숫자이다 



    슈도 코드

    N(숫자의 개수) K(K번째 수)
    A(숫자 데이터 저장 배열)
    for(N만큼 반복하기){
        배열 저장하기
    }
    퀵소트 실행
    K번째 데이터 출력
    
    
    [별도함수]
    퀵소트함수( 시작, 종료, K){
        피벗구하기 함수( 시작, 종료 )
        if ( 피벗 == k ) 종료
        else if (k < 피벗) 퀵소트 실행 (시작, 피벗-1, K)
        else 퀵 소트 수행하기 (피벗 +1 , 종료 ,K)
    }
    
    피벗구하기 함수( 시작, 종료 )
    {
        중앙값을 피벗으로 설정
        i (시작점), j (종료점)
        while(i < j){
            피벗보다 큰 수가 나올때까지 i++
            피벗보다 작은 수가 나올 때까지 j--
            찾은 i와 j데이터를 swap
        }
        피벗 데이터를 나눠진 두 그룹의 경계 index 에 저장하기
    }

     

    구현하기

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st = new StringTokenizer(bf.readLine());
            
            int size = Integer.parseInt(st.nextToken());
            int k = Integer.parseInt(st.nextToken());
    
            st = new StringTokenizer(bf.readLine());
            int[] arr = new int[size];
            for(int i =0; i < size; i++){
                arr[i] = Integer.parseInt(st.nextToken());
            }
            quickSort(arr, 0, arr.length - 1, k - 1);
            System.out.println(arr[k - 1]);
        }
    
    
        private static void quickSort(int[] arr, int startIndex, int endIndex, int k){
            if (startIndex < endIndex){
                int pivot = partition(arr, startIndex, endIndex);
                if (pivot == k){
                    return;
                }else if(k < pivot){
                    quickSort(arr, startIndex, pivot - 1, k);
                }else{
                    quickSort(arr, pivot + 1, endIndex, k);
                }
            }
        }
    
        private static int partition(int[] arr, int startIndex, int endIndex){
            int middlePointer = (startIndex+endIndex)/2;
            int pivot = arr[middlePointer];
            swap(arr, startIndex, middlePointer);
            int leftPointer = startIndex + 1;
            int rightPointer = endIndex;
    
            while( leftPointer <= rightPointer){
                while(leftPointer <= rightPointer && arr[leftPointer] < pivot){
                    leftPointer++;
                }
                while(leftPointer  <= rightPointer && arr[rightPointer] > pivot){
                    rightPointer--;
                }
                if(leftPointer <= rightPointer){
                    swap(arr,leftPointer, rightPointer);
                    leftPointer++;
                    rightPointer--;
                }
            }
    
            swap(arr, rightPointer, startIndex);
            return rightPointer;
        }
    
        private static void swap(int[] arr, int leftIndex, int rightIndex){
            int temp = arr[leftIndex];
            arr[leftIndex] = arr[rightIndex];
            arr[rightIndex] = temp;
        }
    }

    ' > DoIt 알고리즘 코딩테스트' 카테고리의 다른 글

    [기수정렬] 백준 10989번  (0) 2024.11.14
    [병합 정렬] 백준 2751번  (0) 2024.11.12
    [삽입정렬] 백준 11399번  (0) 2024.11.10
    [선택정렬] 백준 1427번  (1) 2024.11.09
    [버블정렬] 백준 1377번  (0) 2024.11.08
Designed by Tistory.