프로그래머스_큰수만들기

임정민·2023년 7월 12일
1

알고리즘 문제풀이

목록 보기
75/173
post-thumbnail

프로그래머스 그리디 문제입니다.

문제

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

주어진 숫자 문자열을 조합하여 가장 큰 수를 만드는 문제입니다.

[나의 풀이1]

(시간 초과)

def solution(number, k):
    from itertools import combinations
    
    number = list(number)
    indexes = [idx for idx in range(len(number))]
    value = 0

    for case in combinations(indexes,k):
        case = list(case)
        origin = list(number)
        cnt = 0
        for i in case:
            del origin[int(i-cnt)]
            cnt += 1
        now = int("".join(origin))
        if now > value:
            value = now
    #print(value)
    return str(value)

최초 구현 시에 숫자들을 조합할 수 있는 모든 경우의 수를 구하여 비교하며 가장 큰 수를 찾는 방식으로 구현하였습니다. 하지만 combinations함수,2중 for문으로 인해 시간초과되는 케이스가 발생하였습니다.🐕🐕🐕

그리하여 문자열을 특정 구간씩 슬라이싱하고 그 중 최고값을 갖는 수를 한개씩 더하는 방식으로 풀고자 하였습니다.

[나의 풀이2]
(시간 초과)

def solution(number, k):
    import numpy as np
    cnt = len(number)-k
    answer = ''
    
    if cnt == 1:
        return max(list(number))
    
    tmp = []
    # tmp = [1,9]
    tmp = number[:1-(cnt)]
    while cnt>0:

        tmp = list(tmp)
        max_idx = np.argmax(tmp)
        
        number = number[max_idx+1:]
        answer += tmp[max_idx]
        
        cnt -= 1

        if cnt == 1:
            answer += max(number)
            cnt -= 1

        tmp = number[:-(cnt-1)]

    return answer

위의 코드는 cnt(최종 문자열의 크기)를 체크하며 후에 더 제거해야하는 숫자들의 갯수를 감안하여 그 앞에 있는 수들 중에서 최고값을 answer에 순차적으로 더하는 방식이었습니다. 하지만 이 방법 또한 여러번의 슬라이싱을 통해 답을 도출하다 보니 또 다시 일부 케이스에서 시간초과가 발생하였습니다. 그리하여
다른 풀이를 참고하게 되었습니다.🐢🐢🐢

[다른 사람의 풀이1]

def solution(number, k):
    answer = [] # Stack
    
    for num in number:
        if not answer:
            answer.append(num)
            continue
        if k > 0:
            while answer[-1] < num:
                answer.pop()
                k -= 1
                if not answer or k <= 0:
                    break
        answer.append(num)
        
    answer = answer[:-k] if k > 0 else answer
    return ''.join(answer)

stack을 이용한 풀이입니다. number의 요소를 돌며 answer안에 아무 숫자도 없을 시에는 일단 append합니다. 그리고 k>0(제거해야할 횟수가 0이 아닐때)
최후방에 있는 숫자를 확인하며 더 작은 값일 시 pop()하고 이때마다 k값을 1개씩 내리고 더 큰값을 append하는 구조입니다. 이 과정을 answer가 비어있거나 제거할 횟수가 0일때(k=0)까지 반복하여 answer를 완성하는 구조입니다.
만약 '4321'과 같이 내림차순으로 되어있는 문자열이라면 pop()하는 과정은 없어 k가 양수이고 answer의 k번째인덱스는 제외하고 출력하는 방식입니다.🐻🐻🐻

비슷한 방식의 풀이로 다른 표현은

[다른 사람의 풀이2]

def solution(number, k):
    answer = [] # Stack
    
    for num in number:
        while k > 0 and answer and answer[-1] < num:
            answer.pop()
            k -= 1
        print(answer)
        answer.append(num)
    print(answer)
        
    
    print(''.join(answer[:len(answer) - k]))
    return ''.join(answer[:len(answer) - k])

solution(['4123'],2)

입력값에 따라 k가 양수일 수 있고 0이 될 수 있기 때문에 return 값에

''.join(answer[:len(answer) - k])

k값이 포함된 수식을 활용한 슬라이싱 방식이었습니다.

감사합니다.

profile
https://github.com/min731

0개의 댓글