새소식

Career/Coding Test

99클럽 코테 스터디 5/99일차 TIL #전화번호 목록(비기너)

  • -
반응형

문제:전화번호 목록호 목록

출처: 프로그래머스

https://school.programmers.co.kr/learn/courses/30/lessons/42577

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

1. 문제 설명

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

2. 문제 해석

단 한 명 완주 X, 나머지 완주
완주하지 못한 사람 이름 return
completion의 돌면서  participant 사람을 하나씩 뽑기
=> 왠지 for문 돌면 효율성 테스트 통과 못할 느낌. 그래도 문제는 일단 푼다.


3. 문제 풀이

풀이 (1) 58.3/100

처음에는 set을 이용해서 중복을 제거하는 방식으로 중복인원을 처리하려고 했는데 그렇게되면 3명 이상의 중복이

발생할 경우 처리가 너무 복잡해졌다.

그래서 단순히 participant에 있는 사람이 completion에 있는지 여부를 파악하면서 participant의 사람을 한 명 씩 제거한다음 남은 사람을 answer로 처리하였다.

def solution(participant, completion):
    
    for person in completion:
        participant.remove(person)
        
    # print(participant)
    answer = participant[0]
            
    return answer

 

정확성 테스트
테스트 1 통과 (0.01ms, 10.3MB)
테스트 2 통과 (0.00ms, 10.1MB)
테스트 3 통과 (0.80ms, 10.2MB)
테스트 4 통과 (3.10ms, 10.3MB)
테스트 5 통과 (4.43ms, 10.3MB)
테스트 6 통과 (0.00ms, 10.3MB)
테스트 7 통과 (0.00ms, 10.2MB)
 
효율성 테스트
테스트 1 실패 (시간 초과)
테스트 2 실패 (시간 초과)
테스트 3 실패 (시간 초과)
테스트 4 실패 (시간 초과)
테스트 5 실패 (시간 초과)

 

정확성은 성공했으나 역시나 예상대로 효율성 테스트를 X같이 실패해버렸다.

for 문을 쓰지 않고 함수를 써야할 것 같은데 방법이 생각이 안났다.

 

풀이 (2) 100/100

 

결국 함수를 쓰는게 답이었다.

 

Counter()

코테 공부를 아주 예전에 잠깐 하고 제대로 안해서 그런지 counter 함수 자체를 까먹었었다.

로직 짤 때 dictonary 쓰는 방법까지도 생각은 했는데 dic를 두 개를 어떻게 처리해야할 지 감이 안와서 못썼는데,

counter를 쓰게 되면 list에 있는 값에 따른 개수를 처리하는데에 아주 유용하게 쓰일 수 있다.

from collections import Counter

lst = ["mislav", "stanko", "mislav", "ana"]
print(Counter(lst))

>> Counter({'mislav': 2, 'stanko': 1, 'ana': 1})

 

이런식으로 counter를 이용하면 list에 있는 문자열들을 key값으로, 이들의 개수를 value로 정리가 한 번에 가능하다.

위 Counter()를 쓴 코드는 다음과 같다.

from collections import Counter

def solution(participant, completion):
    
        # 참가자 리스트와 완료 리스트의 카운트 생성
    participant_counter = Counter(participant)
    completion_counter = Counter(completion)
    
    # 참가자 카운트에서 완료 카운트를 뺀 결과에서 남은 요소 찾기
    incomplete = participant_counter - completion_counter
    
    # 남은 요소 중 하나를 반환
    return list(incomplete.keys())[0]

 

정확성 테스트
테스트 1 통과 (0.06ms, 10.2MB)
테스트 2 통과 (0.03ms, 10.2MB)
테스트 3 통과 (0.40ms, 10.4MB)
테스트 4 통과 (0.78ms, 10.6MB)
테스트 5 통과 (0.46ms, 10.4MB)
테스트 6 통과 (0.05ms, 10.2MB)
테스트 7 통과 (0.04ms, 10.2MB)
효율성 테스트
테스트 1 통과 (30.30ms, 24.2MB)
테스트 2 통과 (41.53ms, 27.8MB)
테스트 3 통과 (55.43ms, 30.1MB)
테스트 4 통과 (66.23ms, 38.9MB)
테스트 5 통과 (63.67ms, 38.9MB)

4. 주요 코드 및 정리

4.1 Counter(): 리스트의 값을 key로, 그 값의 개수를 value로 dictonary로 만들어준다.

4.2 Counter()를 list에 적용하면 편리한 이유.

리스트의 경우 이런식으로 빼는 연산이 불가능하다. 

반면 더하기는 가능.

우리는 빼는 연산을 하고 싶을 때 Counter() 함수가 매우 유용하다.

Counter() 함수를 이용한 빼기 연산

애초에 a - b는 list에서는 불가능 하지만 counter형에서는 가능한 연산이 된다.

a, b를 counter 형으로 만든 다음 빼기를 하게 되면 그 차이가 counter로 반환된다.

그 다음 내가 원하는 key 값만 얻으면 끝.

from collections import Counter

a = ["mislav", "stanko", "mislav", "ana"]
b = ["stanko", "ana", "mislav"]

counter_a = Counter(a)
counter_b = Counter(b)
c =  counter_a - counter_b
print(c)
>> Counter({'mislav': 1})
print(c.keys())
>> dict_keys(['mislav'])
print(list(c.keys()))
>> ['mislav']
print(list(c.keys())[0])
>> mislav

key를 다루는건 dictonary에서 하는 방식과 동일하게 적용한다.

(1) counter의 key 값들을 .keys()로 뽑으면 dict_keys()로 얻어는다.

 counter.keys()

(2) 이를 list에 넣어 key 값들을 리스트화 한다.

list(counter.keys())

(3) 원하는 key 값을 인덱스 값으로 얻어낸다.

list(counter.keys())[0]

 

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.