(Swift) Programmers 괄호 회전하기

SteadySlower·2022년 12월 30일
0

Coding Test

목록 보기
206/305

코딩테스트 연습 - 괄호 회전하기

문제 풀이 아이디어

괄호의 짝을 맞추는 문제는 아주 전형적인 Stack을 활용한 문제입니다. 여는 괄호가 나왔을 때 stack에 push하고 닫는 괄호가 나오면 stack에서 pop해가면서 짝을 맞추면 됩니다. pop했을 때 stack이 비어 있거나 짝이 맞는 괄호가 아니라면 올바른 괄호 문자열이 아닙니다. 마지막에 stack이 empty가 아닌 경우도 올바른 괄호 문자열이 아닙니다.

이 문제는 괄호를 회전하는 부분이 포함되어 있는데요. 이는 아주 간단한 문자열 조작으로 구현할 수 있습니다.

코드

저는 닫는 괄호가 나왔을 때 짝을 맞추는 부분 (대, 중, 소 괄호 유형이 맞는지 확인하는 과정)의 코드가 복잡해질 것 같아서 미리 괄호의 유형을 enum으로 선언해두었습니다. 코드는 좀 더 길지만, 가독성이 높아졌다고 생각합니다.

// 괄호의 유형 (대, 중, 소)
enum PType {
    case large, medium, small
}

// 괄호의 유형을 리턴해주는 extension
extension Character {
    var pType: PType {
        switch self {
        case "[": return .large
        case "]": return .large
        case "{": return .medium
        case "}": return .medium
        case "(": return .small
        case ")": return .small
        default: return .large
        }
    }
}

// 올바른 괄호 문자열인지 확인하는 함수
func isRight(_ s: String) -> Bool {
    // 여는 괄호
    let open: [Character] = ["[", "{", "("]

    var stack = [Character]()

    // 괄호 문자열 전체를 순회
    for c in s {
        // 여는 괄호일 때 push
        if open.contains(c) {
            stack.append(c)
        // 닫는 괄호라면 pop
        } else {
            // stack이 비어 있다면 false
            if stack.isEmpty {
                return false
            }
            let popped = stack.popLast()!
            // pop한 괄호가 짝이 맞지 않다면 false
            if popped.pType != c.pType {
                return false
            }
        }
    }
    
    // 순회가 끝냈을 때 stack이 비어있을 때만 true
    return stack.isEmpty ? true : false
}

func solution(_ s:String) -> Int {
    var s = s
    var ans = 0

    // 괄호를 회전하는 함수
    func moveLeft() {
        let left = s.removeFirst()
        s = s + String(left)
    }

    // 올바른 괄호 문자열인지 확인하고 회전시키면서 모든 회전 케이스에 대해 확인
    for _ in 0..<s.count {
        if isRight(s) { ans += 1 }
        moveLeft()
    }

    return ans
}
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글