파이썬을 이용하여 코딩테스트 문제를 풀어본다
번호로 값에 접근할 수 있는 배열 대신 문자열로 값에 접근할 수 있는 해시를 이용
→ 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)