정렬 범위를 한 칸씩 확장하면서 새롭게 정렬 범위에 들어온 값들을 기존 값들과 비교하여 알맞은 자리에 삽입하는 방법
시간복잡도는 최선의 경우 O(n), 평균/최악의 경우 O(n^2)
def insertion_sort(arr):
for end in range(1, len(arr)):
for i in range(end, 0, -1):
if arr[i-1] > arr[i]:
arr[i-1], arr[i] = arr[i], arr[i-1]
배열에서 위치를 선택하고, 그 위치에 들어갈 값을 찾아 교환하는 방법
시간복잡도는 최선/평균/최악의 경우 O(n^2)
def selection_sort(arr):
for i in range(len(arr)-1):
min_idx = i
for j in range(i+1, len(arr)):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
배열을 순회하면서 인접한 두 개의 데이터를 비교하고 교환하는 방법
시간복잡도는 최선/평균/최악의 경우 O(n^2)
def bubble_sort(arr):
for i in range(len(arr)-1, 0, -1):
for j in range(i):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
재귀적으로 수열을 나눠 정렬한 뒤 합침 -> 주어진 배열을 원소가 하나밖에 남지 않을 때까지 계속 둘로 쪼갠 후에 다시 크기 순으로 정렬
시간복잡도는 최선/평균/최악의 경우 O(nlgn)
def merge_sort(arr):
if len(arr) < 2:
return arr
# 리스트의 길이가 1이 될 때까지 리스트를 둘로 나누기
mid = len(arr) // 2
low_arr = merge_sort(arr[:mid]) # 재귀
high_arr = merge_sort(arr[mid:]) # 재귀
# 두 리스트를 합쳐서 정렬된 리스트 만들기
merged_arr = []
l, h = 0, 0
while l < len(low_arr) and h < len(high_arr):
if low_arr[l] < high_arr[h]:
merged_arr.append(low_arr[l])
l += 1
else:
merged_arr.append(high_arr[h])
h += 1
merged_arr += low_arr[l:]
merged_arr += high_arr[h:]
return merged_arr
우선순위가 같은 원소가 여러 개일 땐 정렬한 결과가 유일하지 않을 수 있음
-> 우선순위가 같은 원소들끼리는 원래의 순서를 따라가도록 하는 정렬
-> Bubble, Insertion, Merge Sort는 Stable Sort
시간복잡도는 최선/평균의 경우 O(nlgn), 최악의 경우 O(n^2)
def quick_sort(arr):
if len(arr) < 2:
return arr
pivot = arr[len(arr)//2]
low_arr, equal_arr, high_arr = [], [], []
for i in range(len(arr)):
if arr[i] < pivot:
low_arr.append(arr[i])
elif arr[i] > pivot:
high_arr.append(arr[i])
else:
equal_arr.append(arr[i])
return quick_sort(low_arr) + equal_arr + quick_sort(high_arr)
각 수의 등장 횟수를 이용하는 정렬
미리 큰 테이블을 만들어두고, 수에 대응되는 원소의 값을 1 증가시켜서 처리하기 때문에 수의 범위가 어느정도 한정적일 때만 사용할 수 있음
자릿수를 이용하는 정렬
from collections import deque
indegree = [0] * (v + 1) # 모든 노드에 대한 진입차수
graph = [[] for _ in range(v+1)] # 각 노드에 연결된 간선 정보
# 방향 그래프의 모든 간선 정보를 입력 받기
for _ in range(e):
a, b = map(int, input().split())
graph[a].append(b) # 정점 A에서 B로 이동 가능
indegree[b] += 1
# 위상정렬 함수
def topology():
answer = [] # 위상정렬 수행 결과
q = deque()
for i in range(1, v+1):
if indegree[i] == 0:
q.append(i) # 진입차수가 0인 노드를 큐에 삽입
result[i] = time[i]
while q:
now = q.popleft()
answer.append(now)
# 해당 원소와 연결된 노드들의 진입차수에서 1 빼기
for i in graph[now]:
indegree[i] -= 1
result[i] = max(result[i], result[now] + time[i]) # 건물 짓는데 드는 최소 시간
if indegree[i] == 0: # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입
q.append(i)
import sys
case = int(sys.stdin.readline())
p, q = map(int, sys.stdin.readline().split())
# 입력 개수를 모를 때
while True:
try:
time, name = input().split()
except:
break
# 내림차순 정렬
list.sort(reverse=True)
# 정렬 조건 추가
arr = sorted(arr, reverse=True, key=lambda x:(x[0].lower(), int(x[1])))
https://school.programmers.co.kr/learn/courses/30/lessons/152995
어떤 사원의 근무 태도 점수와 동료 평가 점수가 다른 사원보다 모두 낮으면 인센티브를 받지 못할 때, 완호(scores[0])의 등수 구하기
def solution(scores):
answer = 1
yanho = scores[0]
scores.sort(key=lambda x: (-x[0], x[1]))
temp = 0
for i in range(len(scores)):
if yanho[0] < scores[i][0] and yanho[1] < scores[i][1]:
return -1
# 이렇게 하면 인센티브를 받지 못하는 사람은 아예 세지 않음
if temp <= scores[i][1]:
# 완호보다 점수가 더 큰 사람이 있으면 완호의 등수가 내려감
if sum(yanho) < scores[i][0] + scores[i][1]:
answer += 1
temp = scores[i][1]
return answer
직원 전체에 대해 값을 구할 필요가 없이 완호만 신경쓰면 된다!!
❓아래처럼 풀면 틀리는 이유
scores.sort(reverse=True)
for i in range(len(scores)):
a, b = scores[i]
if a > yanho[0] and b > yanho[1]:
answer = -1
break
if scores[0][0] > a and scores[0][1] > b:
continue
if a + b > sum(yanho):
answer += 1
[[7, 1], [6, 6], [6, 6], [5, 4], [5, 4]]의 경우, [6,6]>[5,4]라 인센티브를 받지 못하지만 1<4라 제외되지 않는다(오류)