파이썬을 이용하여 코딩테스트 문제를 풀어본다
번호로 값에 접근할 수 있는 배열 대신 문자열로 값에 접근할 수 있는 해시를 이용
→ Python에서 dict
자료형 이용하여 문제를 해결한다
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
participant | completion | return |
---|---|---|
[leo, kiki, eden] | [eden, kiki] | leo |
[marina, josipa, nikola, vinko, filipa] | [josipa, filipa, marina, nikola] | vinko |
[mislav, stanko, mislav, ana] | [stanko, ana, mislav] | mislav |
예제 #1leo는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
예제 #2vinko는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
예제 #3mislav는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.
dict
이용def solution(participant, completion):
d = {}
for x in participant:
d[x] = d.get(x,0) + 1
for x in completion:
d[x] -= 1
dnf = [k for k, v in d.items() if v > 0]
return dnf[0]
def solution(participant, completion):
sorted_parti = sorted(participant)
sorted_compl = sorted(completion)
for p, c in zip(sorted_parti, sorted_compl + ['']):
if p != c:
return p
→ 이므로 해시를 이용한 풀이1보다 오래걸림
탐욕법(Greedy Algorithm)
알고리즘의 각 단계에서 그 순간에 최적이라고 생각되는 것을 선택
(현재의 선택이 마지막 해답의 최적성을 해치지 않을 때 사용 가능)
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
n | lost | reserve | return |
---|---|---|---|
5 | [2, 4] | [1, 3, 5] | 5 |
5 | [2, 4] | [3] | 4 |
3 | [3] | [1] | 2 |
예제 #11번 학생이 2번 학생에게 체육복을 빌려주고, 3번 학생이나 5번 학생이 4번 학생에게 체육복을 빌려주면 학생 5명이 체육수업을 들을 수 있습니다.
예제 #23번 학생이 2번 학생이나 4번 학생에게 체육복을 빌려주면 학생 4명이 체육수업을 들을 수 있습니다.
[1]
리스트를 생성한다.+1
더하고, 잃어버린 사람의 리스트를 돌면서 -1
더한다.1
부터 n
까지 돌면서0
이고 내가 2
이면 둘 다 1
로 바꿔준다2
이고 뒤의 사람이 0
이면 둘 다 1
로 바꿔준다.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([a for a in u[1:-1] if a > 0])
→ 복잡도:
보다 낮은 복잡도 알고리즘은 어렵겠지만
여벌의 체육복을 가져온 학생이 매우 적다면
reserve
)를 정렬하고, 이것을 하나 하나 순서대로 살펴보면서 빌려줄 수 있는 다른 학생을 찾아서 처리한다.def solution(n, lost, reserve):
s = set(lost) & set(reserve)
l = set(lost) - s
r = set(reserve) - s
for a in sorted(r): # 1) k
if a - 1 in l: # 2) m
l.remove(a - 1) # 3) m
elif a + 1 in l:
l.remove(a + 1)
return n - len(l)
여벌의 체육복을 가져온 학생들의 번호(reserve
)를 정렬
→ 복잡도:
코드를 보면 의 개수동안 안에 존재하는 지 찾고, 존재하면 에서 제거(remove 메서드) 함으로, 의 개수를 , 의 개수를 이라고 할 때 복잡도는 으로 보다 더 커지는 것이 아닌지...🤔
[ 20.12.02 추가💬 ]
Python에서 set
의 요소 삭제(remove)와 요소 포함 여부 확인(a in b)에 대한 복잡도는 이다!
참고자료: 파이썬 자료형 및 연산자의 시간 복잡도
어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.
예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.
문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.
number의 자릿수
미만인 자연수입니다.number | k | return |
---|---|---|
1924 | 2 | 94 |
1231234 | 3 | 3234 |
4177252841 | 4 | 775841 |
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
collected.append(num)
collected = collected[:-k] if k > 0 else collected
return ''.join(collected)
0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.
numbers | return |
---|---|
[6, 10, 2] | 6210 |
[3, 30, 34, 5, 9] | 9534330 |
최대 숫자 (1000) 의 글자 개수만큼 반복한 문자열을 key
로 하여 내림차순으로 정렬한다.
def solution(numbers):
str_nums = list(map(str, numbers))
max_num_len = 4
def repeat_max_len(s):
q, r = divmod(max_num_len, len(s))
return s * q + s[:r + 1]
sorted_str_nums_by_max_len = sorted(str_nums, key=repeat_max_len, reverse=True)
if sorted_str_nums_by_max_len[0] == '0':
return '0'
return ''.join(sorted_str_nums_by_max_len)