[백준] 2751 수 정렬하기 2 (python3)

YJ KIM·2022년 11월 23일
0

백준 2731- 수 정렬하기 2

조건

문제

N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.

입력

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

출력

첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.

삽입, 버블, 선택정렬 -> O(n^2) 시간 초과
그러므로 퀵 정렬, 병합정렬, 힙 정렬 중에서 구현하여야 한다

결론적으로, 퀵 정렬은 사용하면 안 된다

1. Quick Sort 사용

퀵 정렬은 최악의 경우에는 O(n^2)의 시간 복잡도를 갖는다.
테스트케이스에 뭐가 있는지는 모르겠지만 그러한 경우가 있는 것 같음

시행착오 순서
1. 구현한 non-in place 퀵 소트 사용 -> 시간초과
2. 혹시해서 in-place quick sort 구현해서 사용해봤지만 -> 시간초과
3. input() 대신 sys.stdin.readline(), non-in place 퀵 소트 사용 -> 메모리 초과

import sys
sys.setrecursionlimit(100000)

def quickSort(array,start,end): #in-place + 중복 값 보존여부 잘 모르겠음 
    if start>=end: return 
    
    pivot=start
    left=start+1; right=end
    
    while(left<=right):
        while(left<=end and array[left]<=array[pivot]):
            left+=1
        while(right>start and array[right]>=array[pivot]):
            right-=1

        if left>right:
            array[right],array[pivot]=array[pivot],array[right]
        else:
            array[right],array[left]=array[left],array[right]

    quickSort(array,0,right-1)
    quickSort(array,right+1,end)

cnt=int(sys.stdin.readline()); lis=[]
for i in range(cnt):
    lis.append(int(sys.stdin.readline()))

quickSort(lis,0,len(lis)-1)

for i in lis:
    print(i)

위 코드는 sys.stdin.readline()과 in-place quick sort 사용한 코드
-> 시간 초과

나: ㅇㅋ 퀵 소트 안 쓸게

2. Merge Sort 사용

시행착오 과정
1. 그냥 머지소트 사용 -> 시간초과
2. input() -> sys.stdin.readline() -> 통과

import sys

def mergeSort(lis)->list:

    if len(lis)<2: return lis

    mid=len(lis)//2
    left=mergeSort(lis[:mid])
    right=mergeSort(lis[mid:])

    #병합
    merged=[]
    l=0; r=0

    while l<len(left) and r<len(right):
        if left[l]<=right[r]:
            merged.append(left[l]); l+=1
        else:
            merged.append(right[r]); r+=1

    merged+=left[l:]
    merged+=right[r:]
    
    return merged

num=int(sys.stdin.readline())
lis=[]
for i in range(num):
    lis.append(int(sys.stdin.readline()))

res=mergeSort(lis)

for j in res:
    print(j)

3. input() 사용 불가

input() 대신 sys.stdin.readline() 써야 시간 초과가 나지 않는다.
어느 정도의 정렬 개념과 input 시간 생각하라고 낸 문제같음

sys.stdin.readline()의 성능은 구글링하면 많이 나온다.

sys 써도 되나 싶은데 뭐 쓰게 해주겠지 싶음 ㅠㅠ 코테에서 sys 라이브러리 막는 곳도 있어서 근데 그럼 이걸 안 내든가 하겠지 ... 그런 생각이 든다.

여담으로 python 내장 함수 sort 써도 통과된다. 퀵 소트 기반으로 구현한 함수라 안 될 줄.. 검색해보니 하이브리드 알고리즘을 사용했다고 한다.

Timesort란

profile
모르면 쓰지 말고 쓸 거면 알고 쓰자

0개의 댓글