알고리즘/프로그래머스
[Python] 프로그래머스 level2 순위 검색
juhi
2021. 4. 1. 23:13
코딩테스트 연습 - 순위 검색
["java backend junior pizza 150","python frontend senior chicken 210","python frontend senior chicken 150","cpp backend senior pizza 260","java backend junior chicken 80","python backend senior chicken 50"] ["java and backend and junior and pizza 100","pyt
programmers.co.kr
풀이 방법
- 정확도 검사 통과는 쉬운데 효율성 검사 통과가 어려웠다.........
- key가 될 값이 많아서 처음에는 arr[java][backend][chicken] 이런식으로 해야하나 했는데, 문자열로 만들어서 하나의 key로 주면 됐다. people[javabackendjuniorpizza] 이런식으로
- 하나의 info에 나올 수 있는 경우의 수는 16가지 이다. 만약 주어진 값이 "java backend junior pizza 150"에 대해 딕셔너리를 저장하면 아래와 같이 나온다.
{
'javabackendjuniorpizza': [150],
'': [150],
'java': [150],
'backend': [150],
'junior': [150],
'pizza': [150],
'javabackend': [150],
'javajunior': [150],
'javapizza': [150],
'backendjunior': [150],
'backendpizza': [150],
'juniorpizza': [150],
'javabackendjunior': [150],
'javabackendpizza': [150],
'javajuniorpizza': [150],
'backendjuniorpizza': [150]
}
- 위와 같은 딕셔너리를 만들어준 후에, 각 쿼리에 대하여 검사한다.
- 리스트에서 하나의 값을 기준으로 크거나 작은 원소의 개수를 구하는 가장 빠른 방법은 이진 탐색이다. (logN)
- 이진 탐색으로 점수에 대해 찾고, 길이에서 찾은 인덱스를 빼주면 그 값보다 크거나 같은 원소의 개수가 나온다.
- bisect.bisect_left(리스트, x)의 리턴 값은 리스트에서 x와 같은 값 중에 가장 앞 인덱스 혹은 리스트에 x가 없다면, x보다 큰 값중 가장 앞 인덱스이다.
전체 코드
from itertools import combinations
from collections import defaultdict
import bisect
def solution(info, query):
answer = []
people = defaultdict(list)
for i in info:
person = i.split()
score = int(person[-1])
people[''.join(person[:-1])].append(score)
for j in range(4):
candi = list(combinations(person[:-1], j))
for c in candi:
people[''.join(c)].append(score)
for i in people:
people[i].sort() # 이진 탐색을 사용하기 위한 정렬
for i in query:
key = i.split()
score = int(key.pop())
key = ''.join(key)
key = key.replace('and', '').replace(' ', '').replace('-', '')
answer.append(len(people[key])-bisect.bisect_left(people[key], score))
return answer
반응형