코딩 테스트 스터디/프로그래머스

[level 2] 튜플

남쪽마을밤송이 2022. 9. 29. 21:53

 문제 

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

 

프로그래머스

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

programmers.co.kr

 사용 언어 

Python3

 풀이 과정 

오랜만에 프로그래머스 문제가 풀고 싶어져서 level 2 중에 하나 골라서 풀었다.

처음에 문제를 잘 이해 못해서 이상하게 풀었는데... 다시 문제를 천천히 읽고 다시 풀었더니 쉽게 풀어서 이제 "구현" 문제가 아닌 level2나  level 3를 위주로 풀면 될 것 같다.

 

이상하게 푼 버전은 다음과 같다. 순서를 고려해야 하는 줄 모르고 무조건 제일 긴 집합을 찾아 인덱스 값을 이용하려고 했다. 그런데 이러면 정답과 원소 순서가 안 맞아서 예제 5개 중 2개만 맞았다.

def solution(s):
    answer = []
    max_length, start, end = 0, 0, 0
    for i in range(1, len(s) - 1):
        if s[i] == "{":
            start = i
        if s[i] == "}":
            end = i
        if end - start > max_length:
            max_length = end - start
            idx = (start, end)
    ansS = int(idx[0])
    ansE = int(idx[1])
    answer = list(map(int, s[ansS+1:ansE].split(",")))
    
    return answer

 

결국 다 지우고 다시 풀었는데 이 문제에서 제일 고민한 부분은 split을 어떤 문자로 할 것인가였다. 처음에 별 생각 없이 ","로 나누면 되겠네 했는데 그러면 집합의 원소들도 다 나눠져버린다. 그래서 split을 못 쓰는 문제인가 했는데 더 고민해보면 "},{"로 나누면 된다는 사실을 깨달을 수 있다. 그러고 나서도 set으로 변환하고 차집합을 unpacking해서 리스트에 append하고 그걸 또 int로 변환하는 과정이... 좀 비효율적이라고 느껴졌는데 어쨌든 답은 나왔다.

 

시간도 나쁘지 않게 한번에 모든 테스트 케이스 통과!

 

 

 제출 답안 

def solution(s):
    answer = []
    splitted = s[2:-2].split("},{")
    for i in range(len(splitted)):
        splitted[i] = set(splitted[i].split(","))
    splitted.sort()
    answer = [*splitted[0]]
    for j in range(1, len(splitted)):
        answer.append(*splitted[j] - splitted[j-1])
        
    return list(map(int, answer))

 

 다른 사람 코드 

1. 정규표현식을 이용한 풀이

def solution(s):

    s = Counter(re.findall('\d+', s))
    return list(map(int, [k for k, v in sorted(s.items(), key=lambda x: x[1], reverse=True)]))

import re
from collections import Counter

import가 밑에 있으면 오류가 날 줄 알았는데 새로운... 발견이다(!?) import는 밑에 있어도 된다는 사실! 이해가 안돼서 찾아보니 다음과 같은 내용을 알 수 있었다.

findall 메소드는 정규식과 매치되는 모든 문자열을 리스트로 돌려준다.
re.findall("\d+", j)이라는 코드는 숫자에 해당한다면 리스트로 돌려주라는 뜻이다.

 확실히 정규표현식을 다룰 줄 알면 문자열 문제들이 훨씬 쉽게 풀리는 경우가 많은 것 같다. 다음에 시간 내서 한 번 개념을 정리해야겠다.

 

2. replace를 이용한 풀이

from collections import Counter
def solution(s):
    new_s = [sss.replace('{','').replace('}','') for sss in s.split(',')]
    return [int(c[0]) for c in sorted(Counter(new_s).items(), key = lambda x: x[1],reverse=True )]

 replace가 그렇게 시간복잡도가 좋은 메소드는 아니라고 생각하지만 코드가 아주 깔끔하다. Counter에 lambda까지... 파이썬 라이브러리를 야무지게 써서 만든 똑똑한 코드인 것 같다.

 

3. 비슷한 풀이

def solution(s):
    answer = []
    s = s[2:-2]
    s = s.split("},{")
    s.sort(key = len)
    for i in s:
        ii = i.split(',')
        for j in ii:
            if int(j) not in answer:
                answer.append(int(j))
    return answer

➡ 비슷한 느낌의 코드지만 더 간단해 보여 돌려봤는데 시간이 나보다 훨씬 길게 나왔다..! 이중 for문을 돌며 매번 if문으로 조건을 확인해서 그런 것 같다.

 

 

출처: 프로그래머스 다른 사람의 풀이

'코딩 테스트 스터디 > 프로그래머스' 카테고리의 다른 글

[Level 2] 모음사전  (0) 2022.10.07
[level 2] 양궁대회  (0) 2022.08.10
[level 2] 주차 요금 계산  (0) 2022.08.01
[level 1] 비밀지도  (0) 2022.07.26
[level 3] N으로 표현  (0) 2022.07.24