Slow is better than NOTHING

Programmers 풀이/[LEVEL 1]

[Python] 프로그래머스 - 문자열 내 마음대로 정렬하기

Jeff_Kang 2019. 10. 11. 22:26
반응형

문제 설명

문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 [sun, bed, car]이고 n이 1이면 각 단어의 인덱스 1의 문자 u, e, a로 strings를 정렬합니다.

제한 조건

  • strings는 길이 1 이상, 50이하인 배열입니다.
  • strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
  • strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
  • 모든 strings의 원소의 길이는 n보다 큽니다.
  • 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.

입출력 예

strings n return
["sun","bed","car"] 1 ["car","bed","sun"]
["abce","abcd","cdx"] 2 ["abcd","abce","cdx"]

 

입출력 예 설명

입출력 예 1
sun, bed, car의 1번째 인덱스 값은 각각 u, e, a 입니다. 이를 기준으로 strings를 정렬하면 [car, bed, sun] 입니다.

입출력 예 2
abce와 abcd, cdx의 2번째 인덱스 값은 c, c, x입니다. 따라서 정렬 후에는 cdx가 가장 뒤에 위치합니다. abce와 abcd는 사전순으로 정렬하면 abcd가 우선하므로, 답은 [abcd, abce, cdx] 입니다.


위 문제는 주어진 String List에서 특정 값을 기준으로 그 값을 가진 String을 정렬하는 문제입니다.

 

저는 문제를 접근할 당시, string 전체가 정렬되는 대상이므로 이 string 하나하나를 표현할 수 있는 key값이 필요하다고 생각했습니다. 따라서, 먼저 전처리 과정으로

def solution(strings, n):
  key_list=[]
  value_list=[]
  for i,v in enumerate(strings):
      key_list.append(i)
      value_list.append(v[n])

다음과 같은 key,value를 만들었습니다. 여기서 Key값은 문제에서 주어진 String List의 각각의 String을 나타낼 수 있는 Index번호이며, value값은 정렬하기 위한 기준 값 입니다. 

[sun, bed, car] 이 주어졌을 때,

strings[0] = "sun"
strings[1] = "bed"
strings[2] = "car"

Key Value
0 'u'
1 'e'
2 'a'

 

다음과 같이 표현됩니다. value_list.append에는 value의 n번째 index를 가져와야합니다. 왜냐하면 우리는 이 값을 기준으로 문제에서 주어진 String을 정렬할거니까요!

이제 (key,value) 값들을 value를 기준으로 오름차순 정렬시킨 결과값을 출력하면 됩니다. 

  dct = dict(zip(key_list,value_list))
  dct = dict(sorted(dct.items(), key =lambda t:t[1]))

다음과 같은 코드를 통해 key_list와 value_list 를 하나의 쌍으로 (key,value) 로 묶고 dictionary 형으로 변환시켜줍니다. 변환된 dict는 key와 item 중 item인('u','e','a') 기준으로 정렬시킵니다. 

-------------------------------------------------
  정렬 전 : {0: 'u', 1: 'e', 2: 'a'}
  정렬 후 : {2: 'a', 1: 'e', 0: 'u'}
-------------------------------------------------

정렬 된 dct 의 key값을 앞에서부터 차례대로 접근하여 출력하면 '각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬'이 되게 됩니다.

answer=[]
for i in dct.keys():
    answer.append(strings[i])

 

하지만, 위와 같은 코드로는 모든 테스트를 통과 할 수 없습니다. 당장 입출력 예시 2번째도 통과하지 못하게 되는데요. 그 이유는 다음과 같은 제한 조건을 간과하였기 때문입니다.

  • 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.

예를 들어, 2번째 입출력 예시의 "abce" 와 "abcd" 를 생각해보겠습니다. 1번 인덱스를 기준으로 정렬한다고 했을 때, 정렬의 기준이 되는 Value는 두 String 모두 'b' 로 동일합니다. 

위의 조건을 만족하기 위해서는 ["abce", "abcd", "cdx"] 은 ["abcd" "abce", "cdx"] 출력 되어야 합니다. 

 

저의 접근 방식은 특정 인덱스를 기준으로 정렬하는 것이기 때문에 인덱스를 뽑아 낸 이후 부터는 String list에 접근할 수 가 없습니다. 

따라서, n번째 인덱스를 뽑아내기 전에 미리 전체 String 에 전처리를 해주어야 합니다. 

strings = sorted(strings)

아주 간단한 코드이지만 위 코드를 통해 주어진 input string list에 대해 마지막 제한 조건이 만족할 수 있게 됩니다. 

 

실제 코딩테스트 문제였다면 다 구현해놓고 코드 한 줄로 인해 전체 문제가 틀리게 되는 불상사가 생길뻔 했던 문제였습니다. 코딩테스트 연습 시 매번 강조하는 점이지만, "제한 조건" 을 잘 읽어보셔야합니다. 

 

전체 코드는 아래와 같습니다.

def solution(strings, n):
    strings = sorted(strings)
    key_list=[]
    value_list=[]
    for i,v in enumerate(strings):
        key_list.append(i)
        value_list.append(v[n])

    dct = dict(zip(key_list,value_list))
    dct = dict(sorted(dct.items(), key =lambda t:t[1]))

    answer=[]
    for i in dct.keys():
        answer.append(strings[i])
    return answer

 

반응형