| 메소드명 | 사용법 | 설명 | 시간복잡도 |
|---|---|---|---|
| append() | 변수명.apend() | 리스트에서 원소를 하나 삽입할 때 사용한다 | O(1) |
| sort() | 변수명.sort() | 기본 정렬 기능으로 오름차순으로 정렬한다. | O(NlogN) |
| sort() | 변수명.sort(reverse=True) | 내림차순으로 정렬한다. | O(NlogN) |
| reverse() | 변수명.reverse() | 리스트의 원소의 순서를 모두 뒤집어 놓는다. | O(N) |
| insert() | 변수명.insert(삽입할 위치 인덱스, 삽입할 값) | 특정한 인덱스 위치에 원소를 삽입할 때 사용한다. | O(N) |
| count() | 변수명.count(특정 값) | 리스트에서 특정한 값을 가지는 데이터의 개수를 셀 때 사용한다. | O(N) |
| remove() | 변수명.remove(특정 값) | 특정한 값을 갖는 원소를 제거하는데, 값을 가진 원소가 여러개 면 하나만 제거한다. | O(N) |
insert 는 O(N)으로 남발하면 시간 초과를 발생시킬 수 있다.
remove 는 O(N)이고, 하나만 제거한다.
remove all 이 없는데, 여러번의 remove 를 쓰기 보다 특정 값의 set 을 만들고, comprehension 으로 처리하는게 좋다.
a = [1, 2, 3, 4, 5, 6, 7]
remove_set = {3, 5}
result = [i for i in a if i not in remove_set]input() 을 이용하여 데이터 입력을 받는다.
5
65 90 75 34 99
3 5 7
를 코드로 처리하면
a = input()
b = list(map(int, input().split()))
n, m, k = map(int, input().split())입력의 개수가 많을 경우 input() 함수를 그대로 사용하지 않는다.
파이썬의 기본 input() 함수는 동작 속도가 느려서 시간 초과로 오답 판정을 받을 수 있기 때문이다. 이 경우 파이썬의 sys 라이브러리에 정의되어 있는 sys.stdin.readline() 함수를 이용한다. readline 을 입력하면 입력 후 엔터(Enter)가 줄 바꿈 기호로 입력되는데, 이 공백 문자를 제거하려면 rstrip() 함수를 사용해야 한다.
import sys
data = sys.stdin.readline().rstrip()파이썬 3.6 이상의 버전부터 f-string 문법을 사용할 수 있다.
f-string은 문자열 앞에 접두사 'f'를 붙임으로써 사용할 수 있는데, f-string을 이용하면 중괄호({}) 안에 변수명을 넣으므로써 자료형을 출력할 수 있다.
heapq는 다익스트라 최단 경로 알고리즘을 포함해 다양한 알고리즘에서 우선순위 큐 기능을 구현하고자 할 때 사용된다.
heapq 외에도 PriorityQueue 라이브러리를 사용할 수 있지만, 코딩 테스트 환경에서는 보통 heapq 가 더 빠르게 동작하므로 heapq 를 사용한다.
파이썬 heap 은 최소 힙(Min Heap)으로 구성되어 있으므로 원소를 힙에 전부 넣었다가 빼는 것만으로도 시간 복잡도 O(NlogN)에 오름차순 정렬이 완료된다.
힙에 원소를 삽입할 때는 heapq.heappush() 메서드를 이용하고, 힙에서 원소를 꺼내고자 할 때는 heapq.heappop() 메서드를 이용한다.
파이썬은 최대 힙(Max Heap)을 제공하지 않는다.
> 힙에 넣을때 - 부호를 붙여서 넣고, 빼낼때 다시 - 부호를 붙이는 방법을 쓴다.
파이썬에서는 이진 탐색을 쉽게 구현할 수 있도록 bisect 라이브러리를 제공한다.
bisect 라이브러리는 '오름차순으로 정렬된 배열'에서 특정한 원소를 찾아야 할 때 매우 효과적으로 사용된다.
bisect_left, bisect_right 는 복잡도 O(logN)에 동작한다.
deque에서는 리스트 자료형과 다르게 인덱싱, 슬라이싱 등의 기능을 사용할 수 없다.
다만, 연속적으로 나열된 데이터의 시작 부분이나 끝부분에 데이터를 삽입하거나 삭제할 때는 매우 효과적으로 사용될 수 있다.
deque는 첫 번째 원소를 제거할 때는 popleft()를, 마지막 원소를 제거할 때는 pop()를 사용한다.
첫 번째 인덱스에 원소 x를 삽입할 때는 append_left(x)를 사용하면, 마지막 원소를 삽입할 때는 append(x)를 사용한다.
collections 라이브러리의 Counter는 등장 횟수를 세는 기능을 제공한다.
from collections import Counter
count = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
print(count)
{'red': 2, 'blue': 3, 'green':1}math 라이브러리의 gcd(a, b) 함수는 최대 공약수를 반환한다.
| 해외 | 코드포스(Codeforces) | http://www.codeforces.com |
|---|---|---|
| 해외 | 탑코더(TopCoder) | http://www.topcoder.com |
| 해외 | 릿코드(LeetCode) | http://www.leetcode.com |
| 해외 | 코드쉐프(CODECHEF) | http://www.codechef.com |
| 국내 | 백준 온라인(BOJ) | http://www.amicpc.com |
| 국내 | 코드업(CodeUp) | http://codeup.kr |
| 국내 | 프로그래머스(Programmers) | http://programmers.co.kr |
| 국내 | SW Expert Academy | http://swexpertacademy.com |
| ? | 코드 시그널 | https://app.codesignal.com |
| ? | 게임코딩 | https://www.codingame.com |
| 국내 | 정올 | http://www.jungol.co.kr |
| 국내 | 생활코딩 | https://opentutorials.org |
GIL : Global Interpreter Lock
PyPy3에서는 실행 시, 자주 사용하는 코드를 캐싱하는 기능이 있기 때문에,
즉 메모리를 더 사용하여 그것을들 저장하고 있어, 실행속도를 개선할 수 있다.
간단한 코드 상에는 Python3가 메모리, 속도 측면에서 우세할 수 있고,
복잡한 코드(반복)을 사용하는 경우에는 PyPy3가 우세하다.
리플릿 : https://replit.com/
파이썬 튜터 : http://pythontutor.com/visualize.html 온라인 GDB : https://www.onlinegdb.com/
복잡도(Complexity)는 알고리즘의 성능을 나타내는 척도이다.
복잡도는 시간 복잡도(Time Complexity)와 공간(Space Complexity)로 나눌 수 있다.
시간 복잡도는 특정한 크기의 입력에 대하여 알고리즘이 얼마나 오래 걸리는지를 의미하고,
공간 복잡도는 특정한 크기의 입력에 대하여 알고리짐이 얼마나 많은 메모리를 차지하는지를 의미한다.
복잡도를 측정함으로써 다음의 2가지를 계산할 수 있다.
- 시간 복잡도 : 알고리즘을 위해 필요한 연산의 횟수 - 공간 복잡도 : 알고리즘을 위해 필요한 메모리의 양
import time
start_time = time.time() # 측정시각 시작
#프로그랰 코드
end_time = time.time() # 측정시각 끝
print("time : ", end_time - start_time) # 수행 시간 출력그리디(Greedy): 탐욕법
현재 상황에서 가장 좋아 보이는 것만을 선택하는 알고리즘
그리디 알고리즘을 이용했을 때 '최적의 해'를 찾을 수 없을 가능성이 다분하다.
파이썬에서는 프로그래머가 직접 자료형을 지정할 필요가 없으며 매우 큰 수의 연산 또한 기본으로 지원한다.
파이썬에서 실수형 변수는 다른 언어와 마찬가지로 유효숫자에 따라서 연산 결과가 원하는 값이 안 나오지 않을 수 있다.
정렬(Sorting)이란 데이터를 특정한 기준에 따라서 순서대로 나열하는 것을 말한다.
선택 정렬(Selection Sort)은 매번 '제일 작은 것을 선택'하는 방식으로 정렬한다.
가장 작은 데이터를 선택해 맨 앞에 두고, 그 다음 작은 데이터를 선택해 두번째 데이터와 바꾸는 과정을 반복한다.
삽입 정렬(Insertion Sort)은 특정한 데이터를 적절한 위치에 '삽입'한다는 의미를 가진다.
삽입 정렬은 특정한 데이터가 적절한 위치에 들어가기 이전에, 그 앞까지의 데이터는 이미 정렬이 되어 있다고 가정한다.
보통은 삽입 정렬이 비효율적이나 정렬이 거의 되어 있는 상황에서는 퀵 정렬 알고리즘보다 더 강력하다.
퀵 정렬(Quick Sort)은 정렬 알고리즘 중에 가장 많이 사용되는 알고리즘이다.
계수 정렬(Count Sort) 알고리즘은 특정한 조건이 부합할 때만 사용할 수 있지만 매우 빠른 정렬 알고리즘이다.
파이썬은 기본 정렬 라이브러리인 sorted() 함수를 제공한다.
sorted()는 퀵 정렬과 동작 방식이 비슷한 병합 정렬을 기반으로 만들어졌는데, 병합 정렬은 일반적으로 퀵 정렬보다 느리지만 최악의 경우에도 시간 복잡도 O(NlogN)을 보장한다는 특징이 있다.
순차 탐색(Sequential Search)이란 리스트 안에 있는 특정한 데이터를 찾기 위해 앞에서부터 데이터를 하나씩 차례대로 확인하는 방법이다.
이진 탐색(Binary Search)는 배열 내부의 데이터가 정렬되어 있어야만 사용할 수 있는 알고리즘이다.
트리는 부모 노드와 자식 노드의 관계로 표현된다.
트리의 최상단 노드를 루트 노드라고 한다.
트리의 최하단 노드를 단말 노드라고 한다.
트리에서 일부를 떼어내도 트리 구조이며 이를 서브 트리라 한다.
트리는 파일 시스템과 같이 계측적이고 정렬된 데이터를 다루기에 적합하다.
다익스트라 알고리즘은 '한 지점에서 다른 특정 지점까지의 최단 경로를 구해야 하는 경우'에 사용할 수 있는 최단 경로 알고리즘이다.
플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)은 '모든 지점에서 다른 모든 지점까지의 최단 경로를 구해야 하는 경우'에 사용할 수 있는 알고리즘이다.
그래프(Graph)란 노드(Node)와 노드 사이에 연결된 간선(Edge)의 정보를 가지고 있는 자료구조를 의미한다.
서로소 집합(Disjoint Sets)이란 공통 원소가 없는 두 집합
서로소 집합 자료구조란 서로소 부분 집합들로 나누어진 원소들의 데이터를 처리하기 위한 자료구조라고 할 수 있다.
서로소 집합 자료구조는 union과 find 이 2개의 연산으로 조작할 수 있다.
합집합(union) 연산은 2개의 원소가 포함된 집합을 하나의 집합으로 합치는 연산이다.
찾기(find) 연산은 특정한 연소가 속한 집합이 어떤 집합인지 알려주는 연산이다.
서로소 집합 자료구조는 union-find(합치기 찾기) 자료구조라고 불리기도 한다.
신장 트리(Spanning Tree)란 하나의 그래프가 있을 때 모든 노드를 포함하면서 사이클이 존재하지 않는 부분 그래프를 의미한다.
이때 모든 노드가 포함되어 서로 연결되면서 사이클이 존재하지 않는다는 조건은 트리의 성립조건이기도 한다.
신장 트리 중에서 최소 비용으로 만들 수 있는 신장 트리를 찾는 알고리즘을 '최소 트리 신장 알고리즘'이라고 한다.
크루시칼 알고리즘(Kruskal Algorithm)은 대표적인 최소 신장 트리 알고리즘이다.
크루시칼 알고리즘을 사용하면 가장 적은 비용으로 모든 노드를 연결할 수 있는데 크루스칼 알고리즘은 그리디 알고리즘으로 분류된다.
트리 자료구조는 노드가 N개일 때 항상 간선의 개수가 N-1개이다.
위상 정렬(Topology Sort)은 정렬 알고리즘의 일종이다.
위상 정렬은 순서가 정해져 있는 일련의 작업을 차례대로 수행해야 할 때 사용할 수 있는 알고리즘이다.
위상 정렬이란 방향 그래프의 모든 노드를 '방향성에 거스르지 않도록 순서대로 나열하는 것'이다.
진입차수(Indegree)란 특정한 노드로 들어오는 간선의 개수를 의미한다.