본문 바로가기

Python

(28)
알고리즘 - 가장 긴 증가하는 부분 수열 문제 (Longest Increasing Subsequence Problem) 가장 긴 증가하는 부분 수열 문제 (Longest Increasing Subsequence, LIS) 는 다이나믹 프로그래밍의 전형적인 문제 중 하나로써, 다이나믹 프로그래밍의 예시로 자주 나오는 문제이다. 비교적 쉬운 O(N^2) 알고리즘과 좀 더 어렵지만 효율적인 O(N log N) 알고리즘이 있다. 부분 수열 어떠한 수열에서 일부 숫자들을 지워서 만들어지는 수열을 부분 수열이라고 한다. 자기 자신도 자기 자신에 대한 부분 수열이라고 볼 수 있다. 예를 들어 [1, 2, 3, 5, 2, 8] 에 대한 부분 수열은 [1], [1, 3, 5] 등이 있다. 증가하는 부분 수열 부분 수열 중 오름차순으로 정렬되어 있는 부분 수열을 증가하는 부분 수열이라고 한다. 예를 들어 [1, 2, 3, 5, 2, 8] ..
Python - 파이썬과 PyPy 파이썬은 강력하고 유연하며, 사용하기 쉬운 언어로 유명하다. 그러나 파이썬의 가장 큰 단점은 속도이다. 파이썬은 굉장히 느리다. 이를 개선시키기 위한 여러 시도들이 있는데, 그 중 PyPy를 알아보려고 한다. 파이썬의 속도 파이썬은 인터프리터 언어이며, 인터프리터로 동작하는 스크립트 언어이다. 인터프리터 언어는 코드 한줄 한줄을 그 때 그 때 기계어로 번역하여 실행한다. 인터프리터와 컴파일러에 대해서는 아래를 참고하도록 하자. https://m.blog.naver.com/ehcibear314/221228200531 컴파일러와 인터프리터의 차이 https://blog.naver.com/ehcibear314/221228096291 우선 윗 글을 먼저 읽고 오는 것이 좋다. 컴파일러, 인... blog.nav..
알고리즘 - 유클리드 호제법을 이용한 최대공약수와 최소공배수 구하기 (Using Euclidean Algorithm to Get GCD and LCM) 유클리드 호제법 유클리드 호제법 (Euclidean Algorithm) 이란 두 수의 최대 공약수 (Greatest Common Divisor, GCD) 를 구하기 위한 알고리즘으로써, 시간 복잡도 O(log N) 의 시간 동안 두 수의 최대 공약수를 구할 수 있다. 유클리드 호제법을 이용한 최대 공약수 구하기는 다음과 같다. 두 수, a와 b중 더 큰 수를 더 작은 수로 나눈다. (a가 더 크다고 가정하자) 이후 구해진 나머지 값으로 b를 나눠준다. (즉 a / b의 나머지 값이 c라고 했을 때, b / c) 이후 구해진 나머지 값으로 c를 나눠준다. (즉 b / c의 나머지 값이 d라고 했을 때, c / d) 이 과정을 나머지 값이 0이 될 때까지 반복해준다. 나머지가 0이 되었다면, 나눠준 값이 곧..
파이썬 알고리즘 관련 시간을 줄이는 팁들 자고로 시간을 줄이는 것은 언제나 알고리즘에 있어 지향해야할 목표점이다. 아직 알고리즘 초보라 편법처럼이라도 시간을 줄이고픈 마음에 팁들이 생길 때마다 추가하려고 한다. 입력 - sys 모듈의 readline() 메서드 사용 보통 입력을 받을 때 input() 메서드를 사용하지만, sys 모듈의 readline()을 사용하면 더 빠른 시간에 입력을 받을 수 있으며, 데이터가 많아질 수록 이 차이는 더 커진다. 리스트 반복하기 - 곱셈 연산자 사용 파이썬의 기능 중 리스트를 반복할 때 곱셈을 사용할 수 있다는 장점이 있다. 똑같은 데이터를 반복적으로 리스트에 넣고 싶을 때, for 과 in range(n)을 사용할 수도 있지만, 곱셈 연산자를 사용하는 것이 더 빠르다. 예) 1억개의 0 넣기 import ..
알고리즘 - 하노이의 탑 재귀적 접근 (Hanoi Tower and Recursive Solving) 하노이의 탑의 규칙은 아래 포스트를 참고한다. https://m.blog.naver.com/jaeyoon_95/221762231876 [프로그래머스] 하노이의 탑 문제 설명하노이 탑(Tower of Hanoi)은 퍼즐의 일종입니다. 세 개의 기둥과 이 기동에 꽂을 수 있는 크기... blog.naver.com 하노이의 탑은 보통 재귀 함수를 사용하여 풀곤 한다. 하노이의 탑을 왜 재귀 함수로 풀 수 있는지, 수학적 접근으로 알아보자. 아래의 하노이의 탑은 하노이의 탑 문제에 대한 풀이를 뜻한다. 먼저 원판이 n개 있다고 했을 때, 한 원판에서 다른 원판까지 옮기는 데 필요한 최소 움직임은 m = 2^n - 1이다. 하노이의 탑의 정답은 언제나 존재한다는 것과, 최소 움직임이 위와 같다는 것을 수학적 귀납..
14. 트리 순회 (Tree Traversal): 파이썬 자료구조와 알고리즘 순회 (Traversal) 란 트리 또는 그래프 같은 연결된 구조에서 객체 (노드) 를 방문하는 데 사용되는 알고리즘이다. 순회 문제는 모든 노드를 방문하는 방법을 찾거나 특정 노드만 방문하는 방법을 찾는 것일 수도 있다. 깊이 우선 탐색 깊이 우선 탐색 (depth-first search, DFS) 란 그래프 또는 트리에서 깊이를 우선하여 탐색하는 알고리즘이다. 그래프의 경우는 방문한 노드를 표시해야 하는데. 그렇게 하지 않는다면 무한 반복에 빠질 수 있기 때문이다. 시간 복잡도는 O(V+E) 이다. V는 도달할 수 있는 노드 수 (vertext), E는 도달한 노드에서 나가는 간선 수 (edge) 다. 깊이 우선 탐색은 후입선출 (LIFO) 구조의 스택을 사용하여 구현한다. 깊이 우선 탐색의 세 가지..
13-2. 이진 탐색 트리와 자가 균형 이진 탐색 트리 (Binary Search Tree and Self-balancing Binary Tree): 파이썬 자료구조와 알고리즘 이진 탐색 트리 이진 탐색 트리 (binary search tree) 는 노드를 정렬된 순서로 유지하는 자료구조이다. 이진 트리로 이루어지며, 각 노드에는 값과 두 자식 노드에 대한 포인터가 있다. 또한 선택적으로, 부모 노드의 포인터를 저장할 수도 있다. 각 노드의 값은 왼쪽 하위 트리의 모든 항목보다 크고, 오른쪽 하위 트리의 모든 항목보다 작다. 즉, 노드의 왼쪽 하위 트리에는 노드의 값보다 작은 값의 노드만 존재한다. 노드의 오른쪽 하위 트리에는 노드의 값보다 큰 값의 노드만 존재한다. 왼쪽과 오른쪽 하위 트리 모두 이진 탐색 트리이다. 중복 노드가 없다. 이진 탐색 트리가 균형 트리인 경우, 노드 검색/삽입/삭제에 대한 시간 복잡도는 O(log n) 이다. 이진 탐색 트리 구현 이진 탐색 트리는..
13-1. 이진 트리 용어와 구현 (Binary Tree Terms and Implementation): 파이썬 자료구조와 알고리즘 이진 트리 (binary tree) 는 노드가 최대 두 개의 자식 노드 (왼쪽, left 와 오른쪽, right) 를 갖는 자료구조이다. 자식 노드는 부모 노드에 대한 참조를 포함할 수 있다. 트리의 루트 노드 (root node) 는 모든 노드의 조상이다. 이진 트리에서 노드의 차수는 최대 2다. 트리에 m개의 내부 노드가 있으며, 각 내부 노드에 두 개의 자식 노드가 있다고 가정한다. 또한 트리에 n개의 말단 노드가 있다면, 트리의 차수는 n-1 이다. 즉, 2m = n + m -1 이며, 따라서 m = n - 1 이다. 여기서 m은 내부 노드의 개수, n은 말단 노드의 개수이다. 용어 그래프와 마찬가지로, 트리도 기본적인 용어를 먼저 살펴보자. 노드 차수 (degree): 자식 수 경로 (path)..