[Algorithm] 가장 큰 수 (스택)

myeonji·2022년 2월 1일
0

Algorithm

목록 보기
25/89

선생님은 현수에게 숫자 하나를 주고, 해당 숫자의 자릿수들 중 m개의 숫자를 제거하여 가장 큰 수를 만들라고 했습니다. 여러분이 현수를 도와주세요.(단 숫자의 순서는 유지해야 합니다) 만약 5276823 이 주어지고 3개의 자릿수를 제거한다면 7823이 가장 큰 숫자가 됩니다.

스택 : LIFO (후입선출), 입구와 출구가 한 곳이다.

이 문제는 입력받은 숫자를 하나씩 새로 만든 리스트에 넣으며 비교하면 된다. 새로 만든 리스트를 pop하거나 append하면 같은 곳에서(맨 왼쪽 혹은 맨 오른쪽) 실행된다.

res = ''.join(map(str, stack))

join 함수는 리스트에 있는 요소를 하나하나 합쳐서 하나의 문자열로 변환하는 함수이다. 함수의 모양은 ''.join(리스트) 혹은 '구분자'.join(리스트) 이다.
여기서는 stack이라는 리스트를 str 형태로 map 하여 문자열로 변환하는 것이다.
stack = [1, 2, 3] 이라면 map(str, stack) = ['1', '2', '3'] 이 된다.

<내 답안>

a, b = map(int, input().split())
li = []
a = str(a)
for i in range(len(a)):
    li.append(int(a[i]))

cnt = 0
ans = [li[0]]
for i in range(1, len(a)):
    if ans[-1] < li[i]:
        while ans != [] and ans[-1] < li[i]:
            ans.pop()
            cnt += 1
            if cnt == b:
                break
        ans.append(li[i])
    else:
        ans.append(li[i])

    if cnt >= b:
        for x in range(i+1, len(li)):
            ans.append(li[x])
        break

if cnt < b:
    for x in range(b-cnt):
        ans.pop()

for x in ans:
    print(x, end='')

실행은 되지만 너무 복잡하다. 간결하고 효율적인 코드로 구현하는 연습이 필요하다.
모범답안처럼 stack에 들어갈 조건들을 모아서 조건문에 and 를 써서 한번에 처리하면 좋을 것 같다.

모범답안에서 몇 가지 팁을 얻었다.

  • num = int(input()) 일 때 123 을 입력하면 num = 123 이다. num을 [1, 2, 3] 처럼 리스트로 바꾸고 싶을 때 어떻게 해야할까?
    처음에는 num = list(num) 을 생각했는데 이는 num = [123] 이 나온다.
    이럴 때는 num = list(map(int, str(num))) 으로 써주면 된다. 먼저 num을 str 형태로 바꾸어야 1 2 3 하나하나에 접근 가능 하다.

  • while stack: 은 stack이라는 리스트가 비어있으면 거짓, 비어있지 않으면 참이다.

  • stack 리스트에서 맨 오른쪽 m 개를 지우고 싶을 땐, stack[:-m]을 하면 처음부터 -m 전까지만 슬라이싱 되어 맨 오른쪽의 m 개를 날릴 수 있다.

<모범답안>

num, m = map(int, input().split())
num = list(map(int, str(num)))  # 리스트화 시키는 법
stack = []
for x in num:
    while stack and m>0 and stack[-1] < x:  # stack 이 비어있으면 거짓, 아니면 참
        stack.pop()
        m -= 1
    stack.append(x)

if m != 0:
    stack = stack[:-m]  # 뒤쪽의 m개 날리기

res = ''.join(map(str, stack))
print(res)

0개의 댓글