본문 바로가기

알고리즘

프로그래머스: 대충 만든 자판

[level 1] 대충 만든 자판 - 160586

문제 링크

성능 요약

메모리: 10.2 MB, 시간: 55.33 ms

구분

코딩테스트 연습 > 연습문제

채점결과

정확성: 100.0
합계: 100.0 / 100.0

제출 일자

2024년 1월 2일 2:5:40

문제 설명

휴대폰의 자판은 컴퓨터 키보드 자판과는 다르게 하나의 키에 여러 개의 문자가 할당될 수 있습니다. 키 하나에 여러 문자가 할당된 경우, 동일한 키를 연속해서 빠르게 누르면 할당된 순서대로 문자가 바뀝니다.

예를 들어, 1번 키에 "A", "B", "C" 순서대로 문자가 할당되어 있다면 1번 키를 한 번 누르면 "A", 두 번 누르면 "B", 세 번 누르면 "C"가 되는 식입니다.

같은 규칙을 적용해 아무렇게나 만든 휴대폰 자판이 있습니다. 이 휴대폰 자판은 키의 개수가 1개부터 최대 100개까지 있을 수 있으며, 특정 키를 눌렀을 때 입력되는 문자들도 무작위로 배열되어 있습니다. 또, 같은 문자가 자판 전체에 여러 번 할당된 경우도 있고, 키 하나에 같은 문자가 여러 번 할당된 경우도 있습니다. 심지어 아예 할당되지 않은 경우도 있습니다. 따라서 몇몇 문자열은 작성할 수 없을 수도 있습니다.

이 휴대폰 자판을 이용해 특정 문자열을 작성할 때, 키를 최소 몇 번 눌러야 그 문자열을 작성할 수 있는지 알아보고자 합니다.

1번 키부터 차례대로 할당된 문자들이 순서대로 담긴 문자열배열 keymap과 입력하려는 문자열들이 담긴 문자열 배열 targets가 주어질 때, 각 문자열을 작성하기 위해 키를 최소 몇 번씩 눌러야 하는지 순서대로 배열에 담아 return 하는 solution 함수를 완성해 주세요.

단, 목표 문자열을 작성할 수 없을 때는 -1을 저장합니다.


제한사항
  • 1 ≤ keymap의 길이 ≤ 100
    • 1 ≤ keymap의 원소의 길이 ≤ 100
    • keymap[i]는 i + 1번 키를 눌렀을 때 순서대로 바뀌는 문자를 의미합니다.
      • 예를 들어 keymap[0] = "ABACD" 인 경우 1번 키를 한 번 누르면 A, 두 번 누르면 B, 세 번 누르면 A 가 됩니다.
    • keymap의 원소의 길이는 서로 다를 수 있습니다.
    • keymap의 원소는 알파벳 대문자로만 이루어져 있습니다.
  • 1 ≤ targets의 길이 ≤ 100
    • 1 ≤ targets의 원소의 길이 ≤ 100
    • targets의 원소는 알파벳 대문자로만 이루어져 있습니다.

입출력 예
keymap targets result
["ABACD", "BCEFD"] ["ABCD","AABB"] [9, 4]
["AA"] ["B"] [-1]
["AGZ", "BSSS"] ["ASA","BGZ"] [4, 6]

입출력 예 설명

입출력 예 #1

  • "ABCD"의 경우,
  • 1번 키 한 번 → A
  • 2번 키 한 번 → B
  • 2번 키 두 번 → C
  • 1번 키 다섯 번 → D
  • 따라서 총합인 9를 첫 번째 인덱스에 저장합니다.
  • "AABB"의 경우,
  • 1번 키 한 번 → A
  • 1번 키 한 번 → A
  • 2번 키 한 번 → B
  • 2번 키 한 번 → B
  • 따라서 총합인 4를 두 번째 인덱스에 저장합니다.
  • 결과적으로 [9,4]를 return 합니다.

입출력 예 #2

  • "B"의 경우, 'B'가 어디에도 존재하지 않기 때문에 -1을 첫 번째 인덱스에 저장합니다.
  • 결과적으로 [-1]을 return 합니다.

입출력 예 #3

  • "ASA"의 경우,
  • 1번 키 한 번 → A
  • 2번 키 두 번 → S
  • 1번 키 한 번 → A
  • 따라서 총합인 4를 첫 번째 인덱스에 저장합니다.
  • "BGZ"의 경우,
  • 2번 키 한 번 → B
  • 1번 키 두 번 → G
  • 1번 키 세 번 → Z
  • 따라서 총합인 6을 두 번째 인덱스에 저장합니다.
  • 결과적으로 [4, 6]을 return 합니다.

풀이

def solution(keymap, targets):
    answer = []

    for target in targets:
        ans = []      

        for t in target:
            temp = []

            for key in keymap:
                if t in key:
                    temp.append(key.find(t) + 1) 

            if len(temp) == 0:
                ans.append(-1)
                break

            else:
                ans.append(min(temp))

        if -1 in ans:
            answer.append(-1)

        else:    
            answer.append(sum(ans))

    return answer

느낀점

target안에 찾는 단어가 keymap안에 각각의 배열에 들어있는지 확인하고 없으면 index를 +1 만큼 증가시켜서 다시 확인하려고 코드를 생각했는데, 이렇게 구현하려고 하니 답도 안보이고 너무 잘못된 방법이라는 생각이 들었다. 그래서 이후에는 targets안에 target의 문자열에서 다시 target문자열안에 각각의 단어마다 keymap들을 돌면서 find 내장함수를 통해 단어가 있다면 해당 값에 +1 만큼 증가시킨 값을 저장한다.

만약에 찾지 못한다면 단어가 없다는 뜻이므로 break를 통해 다음 단어로 넘어간다.(break가 없으면 계속해서 for loop이 끝날때까지 단어들을 순회하기 때문에 시간적으로 낭비)

만약에 처음부터 단어가 없다는게 나오지 않고 중간이나 마지막쯤 단어가 없게 되면 비슷하게 -1을 추가하고 sum을 하기전에 -1인 값이 리스트에 들어있으면 바로 -1을 정답에 추가하면 된다.

level 1을 정답률 순으로 풀고 있는데 정답률이 50% 근처에 다가가니 이전보다 문제가 확실히 어려워진 느낌이 들기도 하지만, 뭔가 문제를 풀면서 이전보다 조금 더 많은 희열이 느껴지는 것 같다.

'알고리즘' 카테고리의 다른 글

프로그래머스: 이웃한 칸  (2) 2024.01.04
프로그래머스: 둘만의 암호  (1) 2024.01.03
프로그래머스: 문자열 나누기  (1) 2024.01.01
프로그래머스: 체육복  (1) 2024.01.01
프로그래머스: 숫자 짝꿍  (1) 2023.12.30