1. 입출력 (Input & Output)
코딩테스트에서 가장 기본이 되는 부분이 바로 입력과 출력입니다. 일반적으로 input()을 사용하지만, 입력 데이터가 많을 경우 실행 속도를 개선하기 위해 sys.stdin.readline()을 사용하는 것이 좋습니다.
띄어쓰기로 구분된 여러 개의 입력값 받기
- input().split()을 사용하면 입력값이 자동으로 공백 기준으로 나뉩니다.
- map(int, input().split())을 사용하면 나뉜 값을 정수형으로 변환할 수 있습니다.
- a, b = map(int, input().split())처럼 여러 변수에 한 번에 저장 가능합니다.
# 예제 입력: 3 5
a, b = map(int, input().split())
print(a, b) # 출력: 3 5
빠른 입출력 (sys.stdin.readline)
- input()은 실행 속도가 느려서, 입력 데이터가 많을 경우 sys.stdin.readline()을 사용하는 것이 필수입니다.
- sys.stdin.readline()을 사용하면 한 줄을 그대로 읽어오기 때문에, 마지막에 개행 문자 \n이 포함됩니다.
- 따라서 rstrip()을 사용하여 개행 문자를 제거하는 것이 일반적입니다.
import sys
input = sys.stdin.readline
n = int(input().rstrip()) # 입력: 7
print(n) # 출력: 7
일반적으로 코딩테스트에서 대량의 데이터를 입력받을 경우 sys.stdin.readline()을 사용하는 것이 필수적입니다.
2. 배열 입력 (List Input)
코딩 테스트에서 여러 줄의 데이터를 배열로 입력받는 경우가 매우 많습니다. 예를 들어, 행렬 입력, 2차원 리스트 입력, 그래프 입력 등이 이에 해당합니다.
여러 줄을 입력받아 2차원 리스트로 저장하기
- 여러 줄의 입력을 받을 때는 반복문을 사용하여 리스트에 값을 추가합니다.
- 리스트 컴프리헨션을 활용하면 더 깔끔한 코드로 작성할 수 있습니다.
'''
예제 입력
3
1 2 3
4 5 6
7 8 9
'''
import sys
input = sys.stdin.readline
N = int(input()) # 줄 개수 입력
data = [list(map(int, input().split())) for _ in range(N)] # N개의 줄을 리스트로 저장
print(data)
# 출력: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
위 방식은 2차원 리스트 입력을 받을 때 가장 많이 사용됩니다. 특히, 그래프 탐색 문제에서 매우 자주 등장합니다.
정수와 배열을 같은 줄에 입력받기 ( * 사용)
- *을 사용하면 첫 번째 값은 개수(n)로 저장하고, 나머지는 배열로 저장할 수 있습니다.
- 예를 들어, 첫 번째 값이 리스트의 크기인 경우, n, *arr = map(int, input().split())를 사용하면 첫 번째 숫자는 변수 n에, 나머지는 리스트 arr에 저장됩니다.
# 입력 예제: 4 3 5 7 9
import sys
input = sys.stdin.readline
n, *data = map(int, input().split())
print(n) # 출력: 4
print(data) # 출력: [3, 5, 7, 9]
위 방식은 첫 번째 숫자가 크기를 나타낼 때 유용합니다.
3. 배열 출력 (List Output)
배열을 공백 없이 출력하기
- join()을 사용하면 리스트의 모든 원소를 공백 없이 문자열로 연결하여 출력할 수 있습니다.
- 단, join()은 문자열을 다룰 때만 사용할 수 있으므로 map(str, arr)을 사용하여 리스트 원소를 문자열로 변환해야 합니다.
arr = [1, 2, 3, 4]
print(''.join(map(str, arr))) # 출력: 1234
배열을 공백으로 구분하여 출력하기
- print(*arr)를 사용하면 리스트의 요소를 공백을 기준으로 출력할 수 있습니다.
- 이는 for문을 사용하여 print(i, end=" ")를 반복하는 것보다 훨씬 간단합니다.
arr = [1, 2, 3, 4]
print(*arr) # 출력: 1 2 3 4
위 방법을 사용하면 for문을 사용하지 않아도 공백으로 구분된 리스트를 출력할 수 있습니다.
코딩테스트에서 출력 형식이 공백으로 구분되어 있을 경우 필수적인 기법입니다.
4. 배열 관련 기능 (List Operations)
코딩테스트에서는 배열을 정렬하거나, 뒤집거나, 특정 값의 개수를 찾거나, 중복을 제거하는 등의 작업을 자주 수행해야 합니다.
배열 뒤집기 (reverse())
- reverse()를 사용하면 리스트의 원소 순서를 뒤집을 수 있습니다.
- [::-1] 슬라이싱을 사용하면 새로운 리스트를 반환합니다.
arr = [1, 2, 3, 4]
arr.reverse()
print(arr) # 출력: [4, 3, 2, 1]
# 슬라이싱 사용
arr = [1, 2, 3, 4]
print(arr[::-1]) # 출력: [4, 3, 2, 1]
배열에서 특정 원소 개수 세기 (count())
- 리스트에서 특정 값이 몇 개 있는지 확인할 때 사용합니다.
arr = [1, 2, 2, 3, 3, 3]
print(arr.count(3)) # 출력: 3
배열에서 중복 제거 (set)
- set()을 사용하면 리스트에서 중복된 원소를 제거할 수 있습니다.
data = [1, 2, 2, 3, 3]
unique_data = list(set(data))
print(unique_data) # 출력: [1, 2, 3] (순서가 보장되지 않음)
5. 정수 관련 기능 (Number Handling)
코딩테스트에서는 최댓값, 최솟값, 진법 변환 등을 다루는 경우가 많습니다. 파이썬에는 이를 간단하게 처리할 수 있는 내장 함수가 있습니다.
최대, 최소값 (sys.maxsize)
- 코딩 테스트에서는 특정 변수의 최댓값을 저장할 때 불필요하게 큰 숫자를 직접 지정하는 것보다 sys.maxsize를 사용하는 것이 더 직관적입니다.
- sys.maxsize는 파이썬에서 표현할 수 있는 가장 큰 정수 값을 의미합니다.
import sys
max_value = sys.maxsize
print(max_value) # 출력: 9223372036854775807 (64비트 시스템 기준)
진법 변환
- bin(), oct(), hex()를 사용하면 10진수를 2진수, 8진수, 16진수로 변환할 수 있습니다.
- int(문자열, 진법)을 사용하면 다른 진법을 10진수로 변환할 수 있습니다.
# 10진수를 2, 8, 16진수로 변환
print(bin(27)) # 0b11011
print(oct(27)) # 0o33
print(hex(27)) # 0x1b
# 다른 진법을 10진수로 변환
print(int('11011', 2)) # 2진수 -> 10진수: 27
print(int('33', 8)) # 8진수 -> 10진수: 27
print(int('1b', 16)) # 16진수 -> 10진수: 27
이 기능은 코딩테스트에서 종종 등장하는 진법 변환 문제를 풀 때 유용합니다.
6. 문자열 관련 기능 (String Handling)
코딩테스트에서는 문자열을 뒤집거나, 특정 문자의 개수를 세거나, 아스키 코드로 변환하는 등의 작업이 자주 등장합니다.
문자열 뒤집기
- 문자열을 뒤집는 방법은 [::-1]을 사용하는 것이 가장 간단합니다.
data = "ABCD"
reversed_data = data[::-1]
print(reversed_data) # 출력: DCBA
문자 <-> 아스키 코드 변환
- ord()는 문자를 아스키 코드(숫자)로 변환합니다.
- chr()는 아스키 코드를 문자로 변환합니다.
print(ord('A')) # 65
print(chr(65)) # 'A'
위 기능은 문자 비교에서 유용하게 쓰입니다.
삼항 연산자 (Ternary Operator)
- if-else 구문을 한 줄로 간단하게 표현할 수 있습니다.
- 코드를 더 깔끔하게 정리할 때 유용합니다.
a, b = 10, 20
# 일반적인 if-else
if a > b:
result = a
else:
result = b
print(result) # 20
# 삼항 연산자
result = a if a > b else b
print(result) # 20
7. 순열과 조합 (itertools 활용)
순열 (Permutations)
- permutations()는 주어진 리스트에서 순서를 고려하여 모든 경우의 수를 생성합니다.
- 예를 들어, [1, 2, 3]에서 2개를 뽑아 나열하는 모든 경우를 구할 수 있습니다.
from itertools import permutations
arr = [1, 2, 3]
print(list(permutations(arr, 2)))
# 출력: [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
조합 (Combinations)
- combinations()는 순서에 상관없이 n개 중에서 r개를 뽑는 모든 경우의 수를 구합니다.
- 즉, (1, 2)와 (2,1)은 같은 경우로 처리됩니다.
from itertools import combinations
arr = [1, 2, 3]
print(list(combinations(arr, 2)))
# 출력: [(1, 2), (1, 3), (2, 3)]
8. 빈도 계산 (Counter 활용)
- Counter는 배열에서 특정 값이 몇 번 등장하는지 빠르게 계산할 수 있습니다.
from collections import Counter
data = "hello world"
counter = Counter(data)
print(counter)
# 출력: {'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1}
9. 힙 (heapq 활용)
코딩테스트에서 우선순위 큐를 사용할 때 힙(heapq)을 활용합니다.
최소 힙 (Min Heap)
- heapq 모듈을 사용하면 항상 가장 작은 값이 먼저 나오는 우선순위 큐를 구현할 수 있습니다.
import heapq
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 4)
print(heapq.heappop(heap)) # 출력: 1 (최소값)
최대 힙 (Max Heap)
- 파이썬의 heapq는 기본적으로 최소 힙만 제공합니다.
- 따라서 값을 넣을 때 -1을 곱하고, 꺼낼 때 다시 -1을 곱하면 최대 힙으로 사용할 수 있습니다.
import heapq
heap = []
heapq.heappush(heap, -3)
heapq.heappush(heap, -1)
heapq.heappush(heap, -4)
print(-heapq.heappop(heap)) # 출력: 4 (최대값)
10. 덱 (Deque 활용)
- deque는 양쪽 끝에서 빠르게 삽입 및 삭제할 수 있는 자료구조입니다.
- appendleft()와 popleft()를 사용하면 O(1)의 시간 복잡도로 빠르게 처리할 수 있습니다.
from collections import deque
deq = deque([1, 2, 3])
deq.appendleft(0) # 왼쪽에 추가
deq.popleft() # 왼쪽에서 제거
print(deq) # 출력: deque([1, 2, 3])