(Swift) Programmers 택배상자

SteadySlower·2023년 4월 4일
0

Coding Test

목록 보기
239/298

문제 풀이 아이디어

문제에서 주어진대로 구현하기만 하면 됩니다. 보조벨트는 선입선출의 방식이므로 stack을 활용합시다. 다만 정말 현실을 “그대로” 구현하기 되면 아래와 같은 실수를 하게 됩니다. 이중 while 문으로 복잡한 if문을 대체하는 테크닉을 익혀두도록 합시다!

코드

func solution(_ order:[Int]) -> Int {

    // 선입선출 보조벨트 = 스택
    var stack = [Int]()
    
    // 현재 컨테이너 벨트에서 나오고 있는 상자
    var now = 1
    
    // 트럭에 실은 짐의 수
    var count = 0

    // now는 최대 order의 길이
    while now <= order.count {
        // 일단 스택에 넣는다.
        stack.append(now)
        // 보조벨트의 마지막이 현재 트럭에 실을 짐의 번호와 동일하면 count에 +1
        while let last = stack.last,
              last == order[count] {
            _ = stack.popLast()!
            count += 1
        }
        
        // 다음 짐을 싣는다.
        now += 1
    }

    return count
}

⭐️ 이중 while 문을 사용하자!

이중 while 문을 사용하기 전에는 아래와 같은 풀이를 사용해서 풀었습니다.

현실에서는 보조벨트를 활용할 때를 생각해봅시다. 현재 컨베이어 벨트에서 나오는 상자를 바로 트럭에 실을 수 있다면 굳이 그 상자를 보조벨트에 넣지 않아도 되겠지요.

하지만 코드를 문제를 풀 때 코드를 더 단순하게 하기 위해서는 현재 컨베이어 벨트에서 나오는 상자를 일단 보조벨트(stack)에 넣었다가 바로 빼도 된다는 점을 기억합시다. 그렇다면 아래처럼 복잡한 조건문의 분기 없이도 이중 while 문을 활용해서 더 쉽게 풀 수 있습니다.

func solution(_ order:[Int]) -> Int {
    
    var stack = [Int]()
    var now = 1
    var count = 0
    
    while count < order.count {
        // 1. 일단 보조벨트에서 꺼낼 것 있는지 확인
        if let last = stack.last,
           last == order[count] {
            _ = stack.popLast()!
            count += 1
        // 2. 보조벨트에 꺼낼 것 없으면 현재 상자를 실을 수 있는 지 확인
        } else if now == order[count] {
            now += 1
            count += 1
        // 3. 현재 실을 것이 없다면 보조벨트에 올린다.
        } else {
            if now <= order.count {
                stack.append(now)
                now += 1
            } else {
                break
            }
        }
        
    }
    
    return count
}
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글