[프로그래머스] 숫자 짝꿍

J. Hwang·2024년 12월 9일
0

coding test

목록 보기
60/108

문제 설명

두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 정수 k(0 ≤ k ≤ 9)들을 이용하여 만들 수 있는 가장 큰 정수를 두 수의 짝꿍이라 합니다(단, 공통으로 나타나는 정수 중 서로 짝지을 수 있는 숫자만 사용합니다). X, Y의 짝꿍이 존재하지 않으면, 짝꿍은 -1입니다. X, Y의 짝꿍이 0으로만 구성되어 있다면, 짝꿍은 0입니다.
예를 들어, X = 3403이고 Y = 13203이라면, X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 3, 0, 3으로 만들 수 있는 가장 큰 정수인 330입니다. 다른 예시로 X = 5525이고 Y = 1255이면 X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 2, 5, 5로 만들 수 있는 가장 큰 정수인 552입니다(X에는 5가 3개, Y에는 5가 2개 나타나므로 남는 5 한 개는 짝 지을 수 없습니다.)
두 정수 X, Y가 주어졌을 때, X, Y의 짝꿍을 return하는 solution 함수를 완성해주세요.


제한 사항

  • 3 ≤ X, Y의 길이(자릿수) ≤ 3,000,000입니다.
  • X, Y는 0으로 시작하지 않습니다.
  • X, Y의 짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.

입출력 예

XYresult
"100""2345""-1"
"100""203045""0"
"100""123450""10"
"12321""42531""321"
"5525""1255""552"

내 풀이

def solution(X, Y):
    if len(X) >= len(Y):
        s1 = Y  # smaller number
        s2 = X # larger number
    else:
        s1 = X   # smaller number
        s2 = Y   # larger number
        
    s1, s2 = list(s1), list(s2)
    
    result = []
    for s in s1:
        if s in s2:
            result.append(s)
            s2.remove(s)
    
    if len(result)==0:
        answer = "-1"       
    else:
        result.sort(reverse=True)
        answer = ''.join(result)
        if int(answer)==0:
            answer = '0'
        else:
            pass
        
    return answer

위는 옳은 답을 내기는 하지만 테스트 11~15에서 시간 초과가 뜬 코드이다. 그래서 반복문을 돌면서 공통된 문자열이 있는지 찾는 부분이 문제일 것이라 생각해서 먼저 두 문자열의 교집합을 찾는 방식으로 시간을 줄여보려고 했으나 X = "5525", Y = "1255" 케이스처럼 한 숫자가 여러 번 중복될 때를 고려하다보니 또 반복문을 쓰게 되어서 그런지 똑같이 시간 초과가 떴다. (아래 코드)

def solution(X, Y):
    intersection = list(set(X)&set(Y))
    
    pairs = []
    for i in intersection:
        n1 = X.count(i)
        n2 = Y.count(i)
        n3 = min(n1, n2)
        for n in range(n3):
            pairs.append(i)

    pairs.sort(reverse=True)
    if len(pairs)==0:
        answer = "-1"
    else:
        answer = ''.join(pairs)
        if int(answer)==0:
            answer = "0"
    return answer

그래서 결국 다른 풀이를 참고하고 나서야 정답을 받을 수 있었다.

def solution(X, Y):
    answer = ''
    for i in range(9, -1, -1):
        answer += (str(i)*min(X.count(str(i)), Y.count(str(i))))
    
    if len(answer)==0:
        answer = "-1"
    elif len(answer)==answer.count('0'):
        answer = "0"
    else:
        pass
    return answer

매우 간결하고 깔끔한 풀이다....


코멘트

제한사항에서 볼 수 있듯이 X와 Y의 자릿수가 매우 크기 때문에 각 자릿수들을 일일이 비교하면 한참 걸리게 된다. 정답 풀이를 보면 그렇게 비교할 것 없이 수는 0에서 9 사이의 수로 이루어지기 때문에 X와 Y에서 0~9가 몇 개가 있는지 카운트하는 방식으로 하면 더 빠르고 효율적으로 찾을 수 있다. 0 → 9가 아니라 9 → 0으로 반복문을 진행하는 이유는 높은 수부터 먼저 찾게 되므로 sort할 필요가 없어지기 때문이다. (sort하는데도 시간이 오래 걸린다고 한다.)
하나 더 충격적인 것은 "0000"을 "0"으로 변환할 때에도 시간초과가 뜰 수 있다는 점이다. 나는 처음에 if int(answer)==0: answer="0"과 같이 변환을 했는데 이렇게 하니 시간 초과가 떴다. 이를 정답 풀이처럼 len(answer)==answer.count('0')처럼 하면 시간 초과없이 빠르게 코드가 돌아간다.


References

https://school.programmers.co.kr/learn/challenges?order=recent
https://chan-lab.tistory.com/36

profile
Let it code

0개의 댓글