Search
📗

파이썬 알고리즘 인터뷰 - 박상길

1. 기본 개념

가. 빅오, 자료형

1) 빅오(big-O)란
입력값(n)이 무한히 커질 때, 함수의 실행 시간의 상한을 설명하는 수학적 표기 방법입니다.
2) 빅오메가(big-omega), 빅세타(big-theta)
빅오는 함수 실행 시간의 상한인 반면, 빅오메가와 빅세타는 각각 하한과 평균에 대한 표기입니다.
3) 분할 상환 분석
‘실행 시간의 상한’만으로 알고리즘의 복잡도를 계산하는 것은 비관적이라는 관점에서 분할 상환 분석이 등장했습니다.
분할 상환 분석 방법은 최악의 경우를 여러 번으로 나눠서 계산합니다. 따라서 실행 시간의 상한에 치닫는 경우가 적을 경우, 상대적으로 복잡도가 낮게 표기됩니다.
4) 자료구조, 자료형, 추상 자료형
자료구조는 데이터를 효율적으로 관리하기 위한 데이터의 관리 구조입니다.
자료형은 프로그래머가 인터프리터에게 데이터를 사용하는 방법을 알려주는 데이터의 속성입니다.
추상 자료형(ADT)는 자료형에 대한 수학적 모델로, 자료형의 행동을 표현하지만 실제 구현 방법은 명시하지 않습니다.

나. 문자열 조작

1) 슬라이싱 내부 동작 원리
슬라이싱 문법의 인덱스가 지정되면 배열 포인터를 토대로 실제 값에 해당하는 객체를 반환합니다.
슬라이싱으로 반환된 객체는 새로운 자료구조에 값을 할당하는 것이나 반복문을 사용하는 것 보다 성능 면에서 우월합니다. 따라사 문자열을 조작하는 경우, 슬라이싱을 우선적으로 고려하는 것이 바람직합니다.
2) 람다와 리스트 컴프리헨션
람다 표현식이란 함수 시그니처를 생략하여 함수의 식을 다른 함수의 인자로 전달하는 것입니다. 예를 들어, 이하의 두 식은 동일한 결과를 가져옵니다.
람다의 단점은 표현식이 길어지면 전체적인 가독성이 떨어진다는 것입니다. 특히 map이나 filter 함수와 함께 사용할 때 가독성이 떨어집니다.
아래의 예시와 같이 다른 함수와 함께 사용하지 않고, 표현식이 짧을 경우에만 사용하는 것이 바람직합니다.
list.sort(key=lambda x: (x.split()[1:], x.split()[0]))
Python
복사
list.sort(key=func) def func(x): return (x.split()[1:], x.split()[0]))
Python
복사
3) dictionary 활용
동일한 키 값을 갖는 요소들을 key:value 형태로 맵핑할 경우, defaultdict을 활용할 수 있습니다.
: 키가 없는 경우에 대비할 수 있습니다.
class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: anagrams = collections.defaultdict(list) for word in strs: anagrams["".join(sorted(word))].append(word) return anagrams.values()
Python
복사
4) sort() vs sorted()
sorted(list): 인자로 전달 받은 리스트의 요소를 직접 조작하지 않습니다. 인자로 받은 리스트를 토대로 정렬한 새로운 리스트를 반환합니다.
주어진 값을 오염시키지 않는다는 점에서 sorted 사용이 권장됩니다.
# 리스트가 아닌 문자열을 반환하려면 아래와 같이 join 연산이 필요합니다 str = “”.join(sorted(list))
Python
복사
list.sort(): 수신 객체인 리스트의 내부 요소를 정렬하며 반환값이 없습니다.
alist = list.sort() # 잘못된 사용법
Python
복사
5) split vs join
split
: 구분자를 토대로 문자열 내 문자를 요소로 갖는 리스트로 반환합니다.
: split() 기본형으로 사용될 때 whitespace characters (ex spaces, tabs, and newlines)를 제거합니다.
s = " hello world " s.split() # ["hello", "world"]
Python
복사
join(): 리스트 요소를 수신객체 전달 받은 값으로 이어서 생성한 문자열을 반환합니다.
class Solution: def reverseWords(self, s: str) -> str: result = s.split() # ["the", "sky", "is", "blue"] result.reverse() # ["blue", "is", "sky", "the"] return " ".join(result) Input: s = " the sky is blue " Output: "blue is sky the"
Python
복사

라. 문자열 문제

1) 팰린드롬(회문) 구별
Queue 활용
정규표현식 & 슬라이싱 활용
2) 문자열 뒤집기
two pointer 활용
pythonic way
3) 문자열 재정렬
람다 활용
4) 가장 빈번한 단어 찾기
리스트 컴프리헨션 & counter 활용
5) 문자열 배열 정렬
정렬과 딕셔너리 활용
6) 부분 문자열 반환 - 어렵다 추후 다시 보자
two pointer 활용

2. 선형 자료구조

가. 배열, 연결 리스트

나. 스택, 큐

다. 데크, 우선순위 큐

1) 파이썬 데크 기본 사용법
queue: Deque = collections.deque() queue.popleft() queue.pop() queue.append(a) # convert to list str_list = list(queue)
Python
복사

라. 해시

3. 비선형 자료구조

가. 그래프

나. 최단 경로

다. 힙

라. 트리

4. 알고리즘

가. 정렬

나. 이진 검색

1) 이진 탐색 트리 vs 이진 검색
차이점은 이진 탐색 트리는 자료구조이고 이진 검색은 알고리즘입니다. 다시 말해, 이진 탐색 트리는 정렬된 형태의 데이터를 저장하고 탐색하는 반면 이진 검색은 정렬된 배열에서 원하는 값을 찾아냅니다.
2) 이진 검색 구현
재귀 구현
재귀 구현 코드
반복 구현
반복 구현 코드
bisect 구현
bisect 모듈의 bisect_left(list, target) , bisect_right(list, target) 을 활용하면 리스트 내 요소를 중 target에 해당하는 요소를 찾고, 해당 요소의 인덱스를 반환합니다.
bisect 활용 코드
3) 회전 정렬된 배열 검색

다. 비트 조작

라. 슬라이딩 윈도우

마. 그리디

바. 분할 정복

사. 다이나믹

참고

파이썬 알고리즘 인터뷰 - 박상길