일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 알고리즘
- C언어
- nestjs typeorm
- 코테
- C++
- @Component
- 파이썬
- 가상면접사례로배우는대규모시스템설계기초
- nestjs auth
- TypeORM
- Nodejs
- spring boot
- 시스템호출
- git
- 스프링
- 카카오 코테
- 프로그래머스
- nestJS
- 구조체배열
- 컴포넌트스캔
- 카카오
- OpenCV
- 해시
- Spring
- AWS
- @Autowired
- 코딩테스트
- python
- 카카오 알고리즘
- thymeleaf
Archives
- Today
- Total
공부 기록장 💻
[알고리즘/해시] 완주하지 못한 선수 (프로그래머스 해시 level 1) 본문
완주하지 못한 선수 (level 1)
문제
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
제한사항
- 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
- completion의 길이는 participant의 길이보다 1 작습니다.
- 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
- 참가자 중에는 동명이인이 있을 수 있습니다.
입출력 예
participant | completion | return |
---|---|---|
["leo", "kiki", "eden"] | ["eden", "kiki"] | "leo" |
["marina", "josipa", "nikola", "vinko", "filipa"] | ["josipa", "filipa", "marina", "nikola"] | "vinko" |
["mislav", "stanko", "mislav", "ana"] | ["stanko", "ana", "mislav"] | "mislav" |
입출력 예 설명
예제 #1"leo"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
예제 #2"vinko"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
예제 #3"mislav"는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.
💡나의 문제 풀이
문제 해결 아이디어
- 해시 문제이므로, Dictionary 사전 자료형을 이용해 key:value 로 완주한 마라톤 선수의 이름으로 단번에 value 값을 찾을 수 있도록 구현해야 겠다는 아이디어를 먼저 얻었다.
- 처음에는 True, False의 값을 value로 지정하고자 했지만, 동명이인 조건을 만족하기 위해서는 단순히 bool값으로는 해결이 불가능함을 인지했다.
participant
리스트를 순회하며, 마라톤 선수의 이름을 key값으로, 해당 이름으로 참가한 인원 수를 value로 갖도록(0부터 초기하여 1씩 추가)playerDict
사전에 추가한다.completion
리스트를 순회하며, 해당 참가자에 대해playerDict
의 value를 1씩 감소시킨다.- 이후 ,
playerDict
를 다시 순회하며 value 값이 1인 참가자의 이름을 리턴한다.
고려사항
- 참가자 중 동명이인 존재 가능 조건
- 동명이인 중 한 명만 완주할 수도 있는 경우를 고려해야 함
작성 코드
def solution(participant, completion):
playerDict = {}
for p in participant:
if p in playerDict:
playerDict[p] += 1
else:
playerDict[p]=1
for c in completion:
playerDict[c]-=1
for p, v in playerDict.items():
if v==1:
return p
def test():
participant = ["mislav", "stanko", "mislav", "ana"]
completion = ["stanko", "ana", "mislav"]
print(solution(participant, completion))
test()
- 첫번째 반복문을 순회할 때
2n
, 두번째 반복문 순회할 때n
이 걸리므로 총 시간 복잡도는3n
이다.
답안 코드 1
Collections
모듈의Counter
함수를 이용participant
리스트의 각 참가자 이름마다 몇 명이 있는지 그 인원을 카운트했고,completion
리스트의 카운트 값들을 뺌- counter value의 값이 1인 지원자의 이름 (key)를 리턴해야 함
- 남아있는 Counter 객체는 남아있는 지원자 이름이기 때문에 그대로 0번째 값을 리턴하면 됨
import collections def solution(participant, completion): answer = collections.Counter(participant) - collections.Counter(completion) return list(answer.keys())[0]
답안 코드 2
- 실제 hash() 함수를 이용해 구현한 방법 (완주하지 못한 선수가 1명이라는 조건을 만족)
participant
를 순회하며 사전dic
에 마라톤 선수의 이름에 대한hash(part)
값을 key로, 이름part
을 value로 하여 삽입- temp에 각
hash(part)
값들을 더해나감
- temp에 각
- 다시
completion
을 순회하며, temp 최종본에서hash(com)
값들을 빼나감 - 마지막에
temp
에 해당하는 값을 key로 하는dic[temp]
value 값을 리턴하면 남아있는 지원자의 이름을 반환하는 것과 같음
- 첫번째 반복문에서는
2n
, 두번째 반복문에서는n
이 걸리므로 총 시간 복잡도는3n
이다. def solution(participant, completion): answer = '' temp = 0 dic = {} for part in participant: dic[hash(part)] = part temp += int(hash(part)) for com in completion: temp -= hash(com) answer = dic[temp] return answer
답안 코드 3
- 해시를 사용하지 않고 sort()를 이용해 이름을 정렬 후, 하나씩 비교하며 이름이 맞지 않는 경우 해당 선수가 완주하지 못했다고 판단하여 리턴
- 문제의 의도와는 다르나, 시간 복잡도 측면에서는 효율적인 코드 구현
- 파이썬의 기본 정렬 함수 sort()는 기본적으로 평균적으로 nlogn, 최악인 경우에도
nlogn
을 보장해므로, 완주하지 못한 선수가 리스트의 가장 마지막에 있다고 치더라도 전체 시간 복잡도는nlogn + n
에 불과하다. def solution(participant, completion): participant.sort() completion.sort() for i in range(len(completion)): if participant[i] != completion[i]: return participant[i] return participant[len(participant)-1]
리뷰
- 해시 문제를 입문하고 이해할 수 있었던 기본 문제
Collections
모듈의Counter
counter1 = Counter(["A", "A", "B"]) counter2 = Counter(["A", "B", "B"]) # 두 Counter 객체 더하기 print(counter1 + counter2) # Counter({'A': 3, 'B': 3}) # 두 Counter 객체 빼기 print(counter1 - counter2) # Counter({'A': 1})
- 뺄샘의 결과로
0
이나 음수가 나온 경우에는 최종 카운터 객체에서 제외가 됨
- 뺄샘의 결과로
- 파이썬 collections 모듈의 Counter 사용법
728x90
반응형
'# CS Study > Algorithms' 카테고리의 다른 글
[알고리즘] 캐시 (프로그래머스 2018 Kakao Blind Recruitment) (0) | 2022.09.19 |
---|---|
[알고리즘/해시] 위장 (프로그래머스 해시 level 2) (1) | 2022.09.19 |
[알고리즘/해시] 순위 검색 (프로그래머스 2021 Kakao Blind Recruitment) (0) | 2022.09.13 |
[알고리즘] 뉴스 클러스터링 (프로그래머스, 2018 Kakao Blind Recruitment) (0) | 2022.09.08 |
[알고리즘/최단경로] leetcode 64 minimum path sum (0) | 2022.08.23 |
Comments