문제는 아래와 같다.
https://programmers.co.kr/learn/courses/30/lessons/42576
자료구조와 알고리즘의 선택
-> 선형 배열(linear array)
사람의 이름은 문자열이기 때문에 배열은 너무나 많은 크기의 공간이 필요하다. 참가자의 이름이 20개 이하의 알파벳 소문자이기 때문에 최악의 경우 26^20의 배열을 필요로 할 수가 있기 때문이다(?)
해시(Hash)
문제의 풀이 및 알고리즘의 구상
코드 작성
def solution(participant, completion):
d = {}
for x in participant:
#dict.get(key, default=None)
#key에 해당하는 value가 있으면 그대로 리턴하고
#없으면 지정값을 리턴한다.
d[x] = d.get(x, 0) + 1
for x in competion:
d[x] -= 1
#did not finish리스트를 컴프리헨션으로 만든다
dnf = [k for k, v in d.items() if v != 0]
answer = dnf[0]
return answer
알고리즘의 시간 복잡도
x를 탐색하는 for 구문 2개 모두 전수조사이기 때문에 O(n)의 시간 복잡도를 가진다. dnf 또한 전수조사이기에 O(n)의 시간 복잡도를 가진다. 따라서 전체의 시간 복잡도는 O(n)이다.
문제는 아래와 같다.
https://programmers.co.kr/learn/courses/30/lessons/42862
자료구조와 알고리즘의 선택
<예제 분석>
n = 5
reserve = [1, 3, 5]
lost = [2, 4]
return 5
탐욕법(Greedy Algorithm)
탐욕법의 아이디어를 적용해보자
알고리즘의 구상
3번의 접근을 이용한 코드 작성
def solution(n, lost, reserve):
u = [1] * (n + 2)
for i in reserve:
u[i] += 1
for i in lost:
u[i] -= 1
for i in range(1, n+1):
if u[i-1] == 0 and u[i] == 2:
u[i-1:i+1] = [1,1]
elif u[i] == 2 and u[i + 1] == 0:
u[i:i+2] = [1,1]
return len([x for x in u[1:-1] if x > 0])
알고리즘의 시간 복잡도
모든 학생수를 탐색하는 순회식의 알고리즘이기 때문에 시간 복잡도는 O(n)이다.
1번의 접근을 이용한 코드 작성
def solution(n, lost, reserve):
s = set(lost) & set(reserve)
l = set(lost) - s
r = set(reserve) - s
for x in sorted(r):
#번호가 작은 학생을 살펴보고
if x - 1 in l:
l.remove(x - 1)
#이후에 번호가 큰 학생을 살펴본다.
elif x + 1 in l:
l.remove(x + 1)
return n - len(l)
알고리즘의 시간 복잡도
sorted(r)은 log(rlogr)만큼의 시간 복잡도를 가진다.
문제는 아래와 같다.
https://programmers.co.kr/learn/courses/30/lessons/42746
문제의 해결방법(알고리즘 구상)
예제에 적용
정렬의 기준을 정하기(패턴의 탐색)
코드 작성
def solution(numbers):
#모든 숫자를 문자열로 변환해주기
numbers = [str(x) for x in numbers]
#변환한 숫자를 4번 반복한 값으로 정렬하기
numbers.sort(key=lambda x : (x*4)[:4], reverse=True)
#숫자가 0인 경우를 걸러주기
if numbers[0] == '0':
answer = '0'
else:
answer = ''.join(numbers)
return answer
알고리즘의 시간 복잡도
시간 복잡도를 지배하는 구문은 numbers.sort(key=lambda x : (x*4)[:4], reverse=True)이다.
이 값에 따라 시간 복잡도가 달라진다.
문제는 다음과 같다.
https://programmers.co.kr/learn/courses/30/lessons/42883
문제의 해결방법(알고리즘 구상)
알고리즘 설계
from itertools import combinations
def solution(number, k):
answer = ''
num_list = list(number)
com_list = list(combinations(num_list, len(number)-k))
com_list.sort(reverse = True)
for number in com_list[0]:
answer += str(number)
return answer
탐욕법으로 해결하기
코드 작성
def solution(number, k):
collected = []
for i, num in enumerate(number):
while len(collected) > 0 and collected[-1] < num and k > 0:
collected.pop()
k -= 1
if k == 0:
collected += list(number[i:])
break
collected.append(num)
collected = collected[:-k] if k > 0 else collected
answer = ''.join(collected)
return answer
알고리즘의 시간 복잡도
알고리즘이 2중 반복문으로 구성되어있기 때문에 n^2의 시간 복잡도를 가질 수 있다고 생각할 수 있지만 while문은 최악의 경우에도 1번 실행이 되기 때문에 for문이 가지는 n 즉, 전체로서는 O(n)의 시간 복잡도를 가지게 된다.