❗️ 계속해서 업데이트 될 예정...
잘못된 부분이 있다면 알려주세요 🙏
값을 특정 순서대로 넣는 알고리즘.
보통 숫자식 순서(Numerical Order)와 사전식 순서(Lexicographical Order)로 정렬한다.
바로 옆에 있는 값과 비교해서 크면 오른쪽, 작으면 왼쪽으로 정렬. 배열 전체를 모두 살펴보는 것이기 때문에 시간복잡도는 항상 O(n**2)
이다.
다른 알고리즘에 비해 매우 비효율적인 알고리즘.
대부분의 경우 퀵 정렬보다 느리지만 일정한 실행속도(항상 O(nlogn)
뿐만 아니라 안정 정렬이라는 점에서 여전히 많이 쓰인다.
다만, 별도의 저장공간에 계속 데이터를 저장하므로 공간이 부족할 경우 퀵 정렬을 이용해야한다.
분할한 후, 다시 정렬하며 합치는 분할 정복 알고리즘이다.
피벗(기준점)을 정해 피벗보다 작으면 왼쪽, 크면 오른쪽과 같은 방식으로 파티셔닝하면서 쪼개 나가는 알고리즘이다.
매우 빠르고 효율적인(평균 O(nlogn)
) 알고리즘이지만 최악의 경우 O(n**2)
가 된다. 이미 정렬된 배열이 들어 올 경우 파티셔닝이 이뤄지지 않기 때문에 버블 정렬과 다를 바 없어진다.
병합 정렬처럼 분할한 후, 다시 정렬하며 합치는 분할 정복 알고리즘이다.
✏️ 내가 작성한 코드
import sys
N = int(input())
s = list(map(int,sys.stdin.readlines()))
s.sort()
for i in s: print(i)
readline
한 줄씩 읽기
readlines
각 줄을 리스트의 요소로 받음
read
모든 줄을 한번에 읽음
✏️ 내가 작성한 코드
import sys
N = int(input())
point_xy = []
for _ in range(N):
x, y = map(int, sys.stdin.readline().split())
point_xy.append([x, y])
sorted_xy = sorted(point_xy)
for i in sorted_xy:
print(i[0],i[1])
sorted
python 에서 sorted는 새로운 리스트를 만들어 정렬해주는데 이때 정렬 기준을 사용자가 직접 정할 수 있다. 디폴트는 이번 문제처럼[[a,b],[c,d],[e,f]]
에 사용하면 첫번째 요소로 한번 정렬한 뒤 요소 값이 같다면 그 다음 요소로 정렬을 시도한다.
Reference
✏️ 내가 작성한 코드
import sys
N = int(input())
point_yx = []
for _ in range(N):
x, y = map(int, sys.stdin.readline().split())
point_yx.append([y, x])
sorted_yx = sorted(point_yx)
for i in sorted_yx:
print(i[1],i[0])
위에 문제에서 x와 y의 자리만 바꿔주면 된다.
✏️ 내가 작성한 코드
import sys
from operator import itemgetter
N = int(input())
member = []
for _ in range(N):
age, name = sys.stdin.readline().split()
member.append([int(age), name])
sorted_mem = sorted(member, key=itemgetter(0))
for i in sorted_mem:
print(i[0],i[1])
파이썬에서 정렬 함수에는
key
라는 매개 변수를 갖고있는데, 이를operator
모듈을 이용하면 다중 정렬일때 어떤 값을 기준으로 정렬할 것인지 정할 수 있다.
위 문제에서는age
를 기준으로 정렬을 시도하는데 조건을 보면나이가 같으면 먼저 가입한 사람이 앞에 오는 순서로 정렬
하라고 한다. 파이썬에서의 정렬은 원래 순서를 보장해주므로 가입한 순서를 보장해준다.
Reference
✏️ 내가 작성한 코드
import sys
N = int(input())
result = []
for _ in range(N):
name, kor, eng, math = sys.stdin.readline().split()
result.append([name, kor, eng, math])
result.sort(key = lambda x: (-int(x[1]), int(x[2]), -int(x[3]), x[0]))
for i in result:
print(i[0])
sorted
에서 사용 가능한 매개변수는sort
에서도 사용 가능하다. 또한 다중 조건에 경우itemgetter
를 사용해도 되지만, 이 문제 같은 경우에는 조건 마다 감소, 증가가 다르므로lambda
표현식을 이용했다.
import sys
from operator import itemgetter
N = int(input())
result = []
for _ in range(N):
name, kor, eng, math = sys.stdin.readline().split()
result.append([name, 100-int(kor), int(eng), 100-int(math)])
result.sort(key = itemgetter(1,2,3,0))
for i in result:
print(i[0])
물론 위 방식으로
itemgetter
를 이용할 수도 있다.
✏️ 내가 작성한 코드
import sys
N = int(input())
arr = [0]*10001
for _ in range(N):
arr[int(sys.stdin.readline())] +=1
for i in range(10001):
if arr[i] != 0:
for _ in range(arr[i]):
print(i)
메모리 초과 문제를 해결하는게 관건인 문제다.
readlines
로 받아도 리스트가 두번 생겨나는 경우가 되어 메모리 초과가 난다.
해결 방법은 위 코드처럼 리스트의 인덱스를 input 값으로 보고 몇 번 반복하는지만 리스트의 해당 인덱스에 기록하면 된다.
✏️ 내가 작성한 코드
import sys
from collections import Counter
N = int(input())
card = list(map(int, sys.stdin.readlines()))
cnt = Counter(sorted(card))
print(cnt.most_common(1)[0][0])
최대한
Counter
에most_common
을 활용해서 풀고 싶었다.
card
를 먼저 정렬을 해서 조건에가장 많이 가지고 있는 정수가 여러 가지라면, 작은 것을 출력
을 해결했다.
그 후로는 간단히most_common
매개 변수를 이용하면 된다. 참고로most_common
는 값이 같을 경우 먼저 들어온 값을 우선 시 한다.
Reference
✏️ 내가 작성한 코드
N, K= map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
print(arr[K-1])