본문 바로가기
알고리즘 문제풀이

[프로그래머스] 큰 수 만들기 (Swift) (스터디)

by SiO2whocode 2022. 3. 6.
728x90

1. 적용 알고리즘과 문제 설명

그리디 문제

정수로 된 문자열이 주어지고, 자연수 k가 주어지면

정수 문자열에서 k개의 문자를 제거하여 얻을 수 있는 수 중 가장 큰 수를 구하는 문제

문자열에서 문자를 제거하는 것이기 때문에 문자열의 순서는 보존되어야 한다.

 

접근방법

큰 수를 얻는게 목적인 만큼, 앞자리 수가 커야한다.

스택 하나를 두고, k개의 카드(앞으로 문자를 제거하는 걸 카드라고 표현한다)가 남아있는 한

새로 들어갈 수가 현재 스택의 맨 위의 수보다 커야한다.는 로직이면

가장 큰 수를 얻을 수 있다.

 

2. 코드에 대한 설명

이걸 코드로 설명하면

k가 0보다 클 때까지는, 스택의 맨 위의 수 >= 새로 들어갈 수 를 만족할 때 까지 스택에서 원소를 뺀다. 그리고 뺄 때마다 k를 1감소 시킨다.

import Foundation

func solution(_ number:String, _ k:Int) -> String {
    var answer = ""

    var _k:Int = k // k를 감소시키기 위해 변수로 선언
    let numbers:[Character] = Array(number) // swift 문자열은 서브스크립트를 제공하지 않기 때문에 편의상 배열로 변환
    let n:Int = numbers.count
    var stack:[Character] = []
    
    for (i,num) in numbers.enumerated() {
    	// 스택에서 값을 빼내는 반복문
        while !stack.isEmpty && _k > 0 && 
        stack.last!.wholeNumberValue! < num.wholeNumberValue! {
            stack.removeLast()
            _k -= 1
        }
        // 정해진 길이를 넘지 않는다면 stack에 append
        if stack.count < n-k {
            stack.append(num)
        }
    }
    return String(stack)
}

3. 시간 복잡도, 공간 복잡도 계산

시간 복잡도 : O(n)

while 문의 반복횟수 : 프로그램 실행 동안 최대 k번 (k번만 뺄 수 있으므로)

append 실행 횟수 : 최대 n번

k < n 이므로 약 2n

append()와 removeLast()는 O(1)

 

공간 복잡도 : O(n)

스택의 최대 크기는 n-k개.  1 <= k < n 이므로 스택에 최대로 들어갈 수 있는 원소의 개수는 n-1개

 

4. 사용 라이브러리

Array의 메서드

- append(Character) : O(1)

- removeLast() : O(1)

 

5. 문제 풀이에 어려웠던 

스택을 사용하는 로직을 생각해내는 것이 어려웠다.

마지막에 스택의 크기를 제한하지 않았다.

9991, K=2 와 같은 반례를 통해서 문제를 발견하여 해결했다.

728x90