코테연습문제
[Programmers/Python] 순위 검색
SI-AH
2023. 4. 27. 13:05
유의했던 사항
1. 정확도와 효율성을 모두 만족해야 함
정확도(18/18), 효율성(0/4)
def solution(info, query):
answer = []
for q in query:
q = q.replace('and', '')
q = q.split()
cnt = 0
for i in info:
i = i.split()
flag = True
if int(i[4]) < int(q[4]):
flag = False
else:
for n in range(4):
if q[n] == '-':
continue
elif q[n] != i[n]:
flag = False
break
if flag:
cnt += 1
answer.append(cnt)
return answer
풀이과정 ( 효율성 통과 X )
1. query에 있는 'and'를 제거하기 위해 replace('and', '')를 사용해 query를 다시 만든다.
2. info에 있는 정보들을 공백을 기준으로 split해 각 지원자별로 정보를 다시 만든다.
3. 각 지원자별 점수가 query에 있는 점수보다 작으면 flag를 False로 바꾼다.
4. q[n] == '-' 일 때, continue
5. q[n] != i[n] 일 때, flag를 False
6. flag가 True일 때 cnt를 1 증가시키고 answer에 append
정확도(18/18), 효율성(4/4)
from itertools import combinations
def solution(info, query):
answer = []
db = {}
for i in info:
inf = i.split()
# information는 조건들, 점수는 score에 따로
information = inf[:-1]
score = int(inf[-1])
# itertools.combinations로 조합 구하기
for n in range(5):
comb = list(combinations([0, 1, 2, 3], n))
for c in comb:
nInfo = information.copy()
for ni in c: # '-'를 포함해 새로운 조건
nInfo[ni] = '-'
cnInfo = '/'.join(nInfo)
# 모든 조건을 딕셔너리로
if cnInfo in db:
db[cnInfo].append(score)
else:
db[cnInfo] = [score]
# 딕셔너리 내 모든 값 정렬 -> lower bound 알고리즘 사용하기 위해
for v in db.values():
v.sort()
for q in query:
qu = [i for i in q.split() if i != 'and']
newQuery = '/'.join(qu[:-1])
qScore = int(qu[-1])
if newQuery in db:
d = db[newQuery]
if len(d) > 0:
start, end = 0, len(d) # lower bound 알고리즘으로 인덱스를 찾아
while start != end and start != len(d):
if d[(start+end) // 2] >= qScore:
end = (start + end) // 2
else:
start = (start + end) // 2 + 1
answer.append(len(d) - start) # 그 인덱스~끝까지 개수를 answer에 append
else:
answer.append(0)
return answer
잘 모르겠어서 여러 블로그와 자료들을 참고했다.....
위 풀이도 혼자 다시 해보라고 하면 못할 거 같음...
그래도 'lower bound'라는 새로운 알고리즘을 알게 됐으니 만족....^^
풀이과정(이라기보단 풀이법..)
-이분탐색을 이용(start, end 이용) → 원하는 값을 찾는 과정
-이 때 query에서 주어진 점수를 기준으로, info에 그 기준 점수보다 크거나 같은 점수를 가진 지원자를 찾아야 함
→ lower bound 이용
알게된 것
1. lower bound 알고리즘
- lower bound : 원하는 값 이상이 처음 나오는 위치를 찾음
- upper bound : 원하는 값 초과가 처음 나오는 위치를 찾음
※ bisect 라이브러리의 bisect_left가 lower bound와 같은 역할을 함