파이썬 알고리즘 문제 풀이 치트시트

파이썬으로 알고리즘을 풀어보면서 자주 찾아보게 되었던 내용을 정리했습니다.

2021-11-04에 씀

파이썬으로 알고리즘을 풀어보면서 자주 찾아보게 되었던 내용을 정리합니다.

입력

시간 단축 - readline 사용하기

1import sys
2input = sys.stdin.readline

스페이스 단위로 나누어진 문자열 입력을 배열로 나눠 담기

1arr = input().strip().split()

스페이스 단위로 나눠진 숫자 입력을 배열로 나눠 담기

1arr = list(map(int, input().split()))

스페이스와 엔터로 나누어진 보드판 입력 받기

1n = int(input()) # n개의 행으로 이루어진 경우
2arr = [input().strip().split() for _ in range(n)]

입력의 개수를 미리 알려주지 않을 경우

1# readline()을 input()으로 사용
2while True:
3 s = sys.stdin.readline().rstrip('\n')
4 if not s:
5 break
6
7# 혹은, 기본 input() 사용
8while True:
9 try:
10 a, b = input().split()
11 print(a + b)
12 except:
13 break

딕셔너리

1dic = {"name": "value", "key_one": 2}
2dic["hi"] = 123
3print(dic["hi"]) # 123

배열

zip()

1weight = [200, 300, 100]
2value = [22, 66, 42]
3for w, v in zip(weight, value):
4 print(w, v)
5
6# (200 22), (300 66), (100 42) 순서로 출력됨

1from collections import deque
2
3queue = deque()
4
5queue.append(2) # 요소 추가
6queue.popleft() # 가장 처음에 들어간 요소를 빼내기

1import heapq
2
3heap = []
4
5heapq.heappush(heap, 3) # 요소 넣기
6heapq.heappop(heap) # 가장 우선순위 높은 요소 빼내기

정렬

1arr = [(5, 1), (88, 4), (77, 1), (4, 3)]
2arr.sort(key=lambda x: (x[1], -x[0]))
3# arr ⇒ [(77, 1), (5, 1), (4, 3), (88, 4)]
4# > 1번 인덱스 요소를 오름차순으로 정렬하고,
5# > 1번 인덱스 요소가 같을 때는 0번 인덱스 요소의 내림차순으로 정렬

이진 탐색

1from bisect import bisect_left, bisect_right
2
3arr = [2,5,5,5,7,9]
4
5print(bisect_left(arr, 2)) # 0
6print(bisect_left(arr, 5)) # 1
7print(bisect_right(arr, 5)) # 4
8print(bisect_right(arr, 9)) # 6
1count = bisect_right(arr, 5) - bisect_left(arr, 5)
2# count == 3

문자/문자열 다루기

1c.isalpha() # 문자로만 되어 있는가? (대문자 or 소문자 or 한글 등의 문자만 인정, 공백이나 특수문자 인정하지 않음)
2c.isalnum() # 문자 혹은 숫자로만 되어 있는가? (공백이나 특수문자 인정하지 않음)
3c.isdigit() # 숫자로 되어 있는가? (거듭제곱 등의 기호까지 인정)
4c.numeric() # 숫자처럼 생긴 글자인가? (제곱근, 분수, 거듭제곱까지 인정)
5c.islower() # 소문자로만 이루어져 있는가?
6c.isupper() # 대문자로만 이루어져 있는가?
1new_lower = c.lower() # c를 소문자로 변경하여 반환, c는 바뀌지 않음
2new_upper = c.upper() # c를 대문자로 변경하여 반환, c는 바뀌지 않음

숫자 다루기

1# 올림
2math.ceil(a)
3
4# 내림 / 음수일 경우 절대값 취하고 +1 (0에서 멀어짐)
5math.floor(a)
6
7# 내림 / 음수일 경우 절대값 취하고 -1 (0에 가까워짐)
8math.trunc(a)
9
10# 반올림
11math.round(a)

수학

자릿수 더하기

1. 재귀

1def sum_digit(n):
2 if n < 10:
3 return n;
4 return (n % 10) + sum_digit(n // 10)

2. 문자열 활용

1def sum_digit(n):
2 return sum(map(int, str(n)))

소수 구하기 - 에라토스테네스의 체

N까지의 모든 정수가 각각 소수인지 아닌지 여부를 알고 싶을 때

  1. 2 ~ N 사이 범위가 담긴 배열을 만든다
  2. 해당 배열의 가장 작은 소수부터 시작하여 그 배수를 해당 배열에서 지운다.
  3. i 다음으로 작은 소수의 배수를 같은 방식으로 배열에서 지운다

for 문을 도는 횟수를 줄이기 위해서 3번의 경우 n의 제곱근보다 약간 큰 수까지만 확인합니다.

1arr = [True] * (n + 1)
2arr[0] = False
3arr[1] = False
4
5for i in range(2, int(n ** 0.6)):
6 if arr[i] == True:
7 j = 2
8 while (i * j) <= n:
9 arr[i * j] = False
10 j += 1
11
12# arr에서 True 값을 가지고 있는 index는 소수입니다.

팩토리얼 구하기

1f = [1] * 1001
2
3for i in range(2, x):
4 f[i] = f[i - 1] * i

최대공약수(GCD), 최소공배수(LCM)

  1. a > b인 자연수에서, r = a % b일 때, GCD(a, b) == GCD(b, r)
  2. r이 0이 될 때 b의 값이 최대공약수가 된다.
1def gcd(a, b):
2 if b > a:
3 gcd(b, a)
4 if b == 0:
5 return a
6 return gcd(b, a % b)
1lcm = a * b / GCD(a, b)

순열, 조합

1import itertools
2
3# 순열
4itertools.permutations(arr, r)
5# n개 중에 r개를 나열하는 경우의 수 (순서 ㅇ)
6
7# 중복순열
8itertools.product(arr, repeat=r)
9# 중복 가능한 n개 중에 r개 나열
10
11# 조합 ->
12itertools.combination(arr, r)
13# n개 중에 r개 선택 (순서 X)

비트마스킹으로 선택 가능한 모든 경우 만들기

1for i in range(1 << n):
2 for j in range(n):
3 # j가 선택되었을 경우
4 if i & (1 << j):
5 print(j, "is in the list")
6 print("")

DFS 기본 형태

1visited = [False] * 9
2
3def dfs(v):
4 visited[v] = True
5 for i in graph[v]:
6 if not visited[i]:
7 dfs(i)

BFS 기본 형태

1visited = [False] * 9
2
3def bfs(start):
4 queue = deque([start])
5 visited[start] = True
6
7 while queue:
8 v = queue.popleft()
9 for i in graph[v]:
10 if not visited[i]:
11 visited[i] = True
12 queue.append(i)

그 외

1xd = [0, 0, 1, -1]
2yd = [1, -1, 0, 0]
3
4now_pos = (3, 4)
5for i in range(4):
6 x, y = now_pos
7 next_pos = (x + xd[i], y + yd[i])
프로필 사진

조예진

이전 포스트
다른 도메인에 쿠키 설정하기
다음 포스트
Next.js에서 Ant Design primary color 변경하기