코드
def solution(keymap, targets):
# 키맵에서 각 문자 최소 누르기 횟수를 저장
char_to_min_press = {}
for key in keymap:
for idx, char in enumerate(key):
if char in char_to_min_press:
char_to_min_press[char] = min(char_to_min_press[char], idx + 1)
else:
char_to_min_press[char] = idx + 1
# 결과를 저장할 리스트
result = []
for target in targets:
total_presses = 0
for char in target:
if char in char_to_min_press:
total_presses += char_to_min_press[char]
else:
# 문자를 작성할 수 없는 경우
total_presses = -1
break
result.append(total_presses)
return result
코드 해설
1. 최소 누르기 횟수 사전 생성
char_to_min_press = {}
for key in keymap:
for idx, char in enumerate(key):
if char in char_to_min_press:
char_to_min_press[char] = min(char_to_min_press[char], idx + 1)
else:
char_to_min_press[char] = idx + 1
- 각 문자에 대해 키맵에서 가장 적게 눌러야 하는 횟수를 저장합니다.
- 키맵에서 idx는 0부터 시작하므로, 실제 키를 누르는 횟수는 idx + 1입니다.
- 동일한 문자가 여러 키에 할당된 경우, 최소 누르기 횟수를 유지합니다.
2. 대상 문자열 변환
for target in targets:
total_presses = 0
for char in target:
if char in char_to_min_press:
total_presses += char_to_min_press[char]
else:
total_presses = -1
break
result.append(total_presses)
- 각 target 문자열의 문자를 확인하며, 최소 누르기 횟수를 합산합니다.
- 만약 키맵에 없는 문자가 있다면 작성 불가능하므로 -1을 저장하고 중단합니다.
3. 결과 반환
return result
- 각 문자열의 최소 누르기 횟수를 결과 리스트에 저장하고 반환합니다.
입출력 예제
예제: keymap = ["ABACD", "BCEFD"], targets = ["ABCD", "AABB"]
이 예제에서 목표는 targets에 있는 각 문자열을 작성하기 위해 최소 누르기 횟수를 계산하는 것입니다.
1. keymap 처리: 최소 누르기 횟수 계산
keymap의 각 문자를 순회하며, 해당 문자를 입력하기 위해 필요한 최소 횟수를 기록합니다.
첫 번째 키맵: "ABACD"
- 'A': 1번 누르면 입력 가능 → {'A': 1}
- 'B': 2번 누르면 입력 가능 → {'A': 1, 'B': 2}
- 'A': 이미 존재, 최소값 유지 → {'A': 1, 'B': 2}
- 'C': 4번 누르면 입력 가능 → {'A': 1, 'B': 2, 'C': 4}
- 'D': 5번 누르면 입력 가능 → {'A': 1, 'B': 2, 'C': 4, 'D': 5}
두 번째 키맵: "BCEFD"
- 'B': 첫 번째 위치 → 최소값 갱신: min(2, 1) → {'A': 1, 'B': 1, 'C': 4, 'D': 5}
- 'C': 두 번째 위치 → 최소값 갱신: min(4, 2) → {'A': 1, 'B': 1, 'C': 2, 'D': 5}
- 'E': 세 번째 위치 → 새로 추가: {'A': 1, 'B': 1, 'C': 2, 'D': 5, 'E': 3}
- 'F': 네 번째 위치 → 새로 추가: {'A': 1, 'B': 1, 'C': 2, 'D': 5, 'E': 3, 'F': 4}
- 'D': 다섯 번째 위치 → 최소값 유지: {'A': 1, 'B': 1, 'C': 2, 'D': 5, 'E': 3, 'F': 4}
최종 char_to_min_press 결과:
{'A': 1, 'B': 1, 'C': 2, 'D': 5, 'E': 3, 'F': 4}
2. targets 처리: 최소 누르기 횟수 계산
첫 번째 문자열: "ABCD"
- 'A': 1번 누름.
- 'B': 1번 누름.
- 'C': 2번 누름.
- 'D': 5번 누름.
총합: 1 + 1 + 2 + 5 = 9
두 번째 문자열: "AABB"
- 'A': 1번 누름.
- 'A': 1번 누름.
- 'B': 1번 누름.
- 'B': 1번 누름.
총합: 1 + 1 + 1 + 1 = 4
최종 결과
result = [9, 4]
코드의 흐름 설명
- keymap을 순회하며 최소 누르기 횟수 계산:
- 각 키맵의 문자와 위치를 기록.
- 중복 문자가 등장하면, 기존 최소값과 비교해 더 작은 값을 저장.
- targets의 각 문자 처리:
- char_to_min_press에서 해당 문자의 값을 가져와 누르기 횟수를 더함.
- 만약 char_to_min_press에 없는 문자가 있다면, 해당 문자열은 작성 불가 → 1 저장.
핵심 포인트
- 효율적인 문자 검색: 딕셔너리(char_to_min_press)를 사용해 O(1)의 복잡도로 최소 누르기 횟수를 가져옴.
- 문자열 탐색: targets를 순회하면서 각 문자의 누르기 횟수를 더함.
- 예외 처리: 작성 불가한 문자열은 1을 반환.
- 시간 복잡도:
- 키맵 크기: O(n * m) (n: 키맵 길이, m: 각 키의 길이).
- 대상 문자열 크기: O(t * l) (t: 타겟 문자열 수, l: 타겟 문자열 길이).
- 총 시간 복잡도: O(n * m + t * l).
관련 문법
- enumerate:
- 리스트를 순회하며 인덱스와 값을 동시에 가져옴.
- 사용 예: for idx, char in enumerate(key):
- dict 활용:
- 키를 사용해 문자 최소 누르기 횟수를 빠르게 조회.
✅ 알고리즘 유형
- 해시맵(Hash Map, 딕셔너리) 활용
- char_to_min_press 딕셔너리를 사용하여 각 문자에 대한 최소 키 입력 횟수를 저장합니다.
- 이를 통해 문자 입력 시 빠르게 최적의 키 입력 횟수를 찾을 수 있음 (O(1) 조회 속도).
- 그리디(Greedy) 알고리즘
- 각 target 문자열을 구성하는 데 필요한 최소 키 입력 횟수를 탐색할 때,
항상 최소한의 입력 횟수를 선택하여 더합니다. - 즉, 현재 상황에서 가장 적은 키 입력을 하는 방법을 선택하는 전략입니다.
- 각 target 문자열을 구성하는 데 필요한 최소 키 입력 횟수를 탐색할 때,
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
프로그래머스 | Python | Greedy | 문자열 나누기 (Lv.1) (0) | 2025.03.02 |
---|---|
프로그래머스 | Python | 단순구현 | 둘만의 암호 (Lv.1) (0) | 2025.02.27 |
프로그래머스 | Python | Brute Froce | [PCCE 기출문제] 9번 / 이웃한 칸 (Lv.1) (0) | 2025.02.27 |
프로그래머스 | Python | 그리디 | 체육복 (Lv.1) (0) | 2025.02.27 |
프로그래머스 | Python | stack, 자료구조 | 햄버거 만들기 (Lv.1) (0) | 2025.02.27 |