[Programmers] 순위 검색
Date:
[Programmers] 순위 검색
Problem URL : 순위 검색
풀이1 (Python)
from itertools import combinations as comb
from collections import defaultdict
def solution(infos, queries):
answer = []
info_dict = defaultdict(list)
for info in infos:
info = info.split()
key_list = info[:-1] # key를 만들 재료들(점수 제외)
score = int(info[-1])
for i in range(5):
for c in comb(key_list, i):
key = ''.join(c) # key 생성
# key 별 리스트에 append
# key가 없어도 에러가 나지 않는 이유는 defaultdict이기 때문
info_dict[key].append(score)
for key in info_dict.keys():
info_dict[key].sort() # key 별 점수 리스트 정렬
for query in queries:
query = query.split(' ')
score = int(query[-1])
key_list = query[:-1] # query key를 만들 재료들(점수 제외)
for i in range(3):
key_list.remove('and') # key 재료들에서 and 제거
while '-' in key_list:
key_list.remove('-') # key 재료들에서 - 제거
key = ''.join(key_list) # key 생성
scores = info_dict[key]
# scores가 비어있지 않으면 이분 탐색
if len(scores) > 0:
start, end = 0, len(scores) - 1
lower_bound = -1 # 초기값이 -1임에 주의, 0보다도 아래여야 한다.
while end >= start:
mid = (start + end) // 2
if scores[mid] >= score:
end = mid - 1
else:
lower_bound = mid # score보다 낮은 점수일 때 lower_bound 갱신
start = mid + 1
answer.append(len(scores) - 1 - lower_bound)
# scores가 비어있으면
else:
answer.append(0)
return answer
풀이 2(Python)
from collections import defaultdict
def solution(infos, queries):
answer = []
info_dict = defaultdict(list)
for info in infos:
info = info.split()
score = int(info[-1])
key_element = [(info[0],'-'), (info[1],'-'), (info[2],'-'), (info[3],'-')] # key 재료들
key = ''
for i in range(2):
for j in range(2):
for k in range(2):
for l in range(2):
key = key_element[0][i] + key_element[1][j] + key_element[2][k] + key_element[3][l]
info_dict[key].append(score)
key =''
for key in info_dict.keys():
info_dict[key].sort() # key 별 점수 정렬
for query in queries:
query = query.split(' ')
score = int(query[-1])
key_element = query[:-1] # query key를 만들 재료들(점수 제외)
for i in range(3):
key_element.remove('and') # key 재료들에서 and 제거
key = ''.join(key_element) # key 생성
scores = info_dict[key]
# scores가 비어있지 않으면 이분 탐색
if len(scores) > 0:
start, end = 0, len(scores) - 1
lower_bound = -1 # 초기값이 -1임에 주의, 0보다도 아래여야 한다.
while end >= start:
mid = (start + end) // 2
if scores[mid] >= score:
end = mid - 1
else:
lower_bound = mid # score보다 낮은 점수일 때 lower_bound 갱신
start = mid + 1
answer.append(len(scores) - 1 - lower_bound)
# scores가 비어있으면
else:
answer.append(0)
return answer
Comments
풀이 2는 풀이1에서 조금 수정했다.
코드는 더 깔끔해졌지만, 효율은 오히려 떨어졌다…
문득 이진 탐색과 파라메트릭 서치의 차이점이 궁금해서 찾아보았다. (링크1) (링크2) (링크3)
읽어보면 최적화 문제를 결정 문제로 바꿔서 푸는 것이 파라메트릭 서치라고 한다.
종만북 450p를 시간날 때 읽어봐야겠다.
댓글