[프로그래머스 LV2] 순위 검색

Junyoung Park·2021년 12월 31일
0

코딩테스트

목록 보기
34/631

1. 문제 설명

순위 검색

2. 문제 분석

정보를 사전에 저장하고 조건에 해당하는 사람들의 전체 수를 카운트하는 문제로 딕셔너리를 활용할 때 효율적으로 풀 수 있다. 풀이 시간을 줄이기 위해 이진탐색 함수, 정렬 함수 등 또한 사용했다. 주어진 공간이 넉넉할 때 비교문보다 미리 기록해 두는 과정을 통해 극적으로 시간 효율성이 증가할 수 있음을 실감했다.

3. 나의 풀이

1.

from bisect import bisect_left

def solution (info, query):
    people = {'cpp': [], 'java': [], 'python': [], 'backend': [], 'frontend': [], 'junior': [],
              'senior': [], 'chicken': [], 'pizza': []}
    scores = {}

    for idx, person in enumerate(info):
        person = person.split(' ')
        for data in person[:-1]:
            people[data] += [idx]
        scores[idx] = int(person[-1])
    new_scores = sorted(scores.values())

    result = []
    for qu in query:
        qu = qu.split(' ')
        while 'and' in qu:
            qu.remove('and')
        while '-' in qu:
            qu.remove('-')
        if len(qu) == 1:
            idx = bisect_left(new_scores, int(qu[-1]))
            total = len(new_scores) - idx
            result.append(total)

        else:
            member = set(people.get(qu[0]))
            for question in qu[1:-1]:
                member = member & set(people.get(question))
            total = 0
            for idx in member:
                if scores.get(idx) >= int(qu[-1]): total += 1
            result.append(total)
    return result
  • 처음에는 주어진 조건(언어별, 직군별, 연차별, 음식별)을 키로 한 딕셔너리에 각 인덱스를 저장했고, 조건을 모두 만족하는 인덱스 집합 중 마지막으로 점수를 만족하는 이들의 수를 카운트했다. 이 경우 문제를 풀 수는 있었지만 효율성 측면에서 매우 떨어져 새로운 방법을 고안해야 했다.

2. 딕셔너리 활용

from bisect import bisect_left
from itertools import combinations
def solution(info, query):
    infos = {}
    scores = []
    for person in info:
        person = person.split(' ')
        score = int(person[-1])
        person = person[:-1]
        scores.append(score)
        for i in range(1, 5):
            combis = list(combinations(person, i))
            for comb in combis:
                comb = ' '.join(comb)
                if not infos.get(comb):
                    infos[comb] = [score]
                else:
                    infos[comb].append(score)

    scores.sort()
    result = []
    for qu in query:
        qu = qu.split(' ')
        while 'and' in qu:
            qu.remove('and')
        while '-' in qu:
            qu.remove('-')
        question = ' '.join(qu[:-1])
        score = int(qu[-1])
        
        if not question:
            idx = bisect_left(scores, score)
            result.append(len(scores)-idx)
        elif infos.get(question):
            people = infos.get(question)
            people.sort()
            idx = bisect_left(people, score)
            result.append(len(people)-idx)
        else:
            result.append(0)
        
    return result
  • 조합을 통해 모든 경우의 수를 담아두고 점수를 저장한다. 주어진 조건에서 '-'를 없애고 조건을 만든 뒤 그 안에 점수를 충족하는 원소의 수를 카운트한다. 이때 '-'를 모두 지었기 때문에 가능한 수가 세 가지 생기는데, '점수만 만족하면 되는' 경우, '사전에서 찾을 수 있는 경우', '조건이 있으나 사전에서 찾을 수 없는 경우'이다. 점수만 만족할 경우 점수 이상의 인덱스만 찾으면 되기 때문에 별도로 만들어놓은 scores 리스트로, 사전을 확인할 때에는 사전 value로 기록된 리스트를 통해, 그 이외에는 0을 return한다. 마지막 경우의 수를 '-'를 없애놓은 상황에서 고려해야 한다는 사실을 인지하지 못했다가 런타임 에러가 뜬 경우를 보고 겨우 다시 해결하게 되었다.
profile
JUST DO IT

0개의 댓글