Swift) 2020 KAKAO BLIND RECRUITMENT - 괄호 변환

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문자열 + 재귀 + 구현 문제. 오랜만에 알고리즘을 푼지라 시간이 많이 걸렸다. 주의할점은 괄호를 변경할 때 문자열을 뒤집는게 아닌 괄호를 뒤집어야 한다. ( 를 )로 뒤집는 것. 문자열과 재귀, 구현을 어느 정도 이해하고 있으면 그리 어려운 문제는 아닌듯 하다.

import Foundation

func checkIsBalance(_ p: String) -> Bool {
    let strArr = Array(p)
    var startCount: Int = 0
    var endCount: Int = 0
    for str in strArr {
        if str == "(" {
            startCount += 1
        } else {
            endCount += 1
        }
    }
    
    return startCount == endCount
}

func splitBalanceStr(_ p: String) -> (String, String) {
    var startCount: Int = 0
    var endCount: Int = 0
    var point = 0
    for str in Array(p) {
        if str == "(" {
            startCount += 1
        } else {
            endCount += 1
        }
        if startCount == endCount {
            break
        }
        point += 1
    }
    let uIndex = p.index(p.startIndex, offsetBy: point)
    let u = String(p[p.startIndex...uIndex])
    if point == p.count-1 {
        return (u, "")
    }
    let vIndex = p.index(p.startIndex, offsetBy: point+1)
    let endIndex = p.index(p.endIndex, offsetBy: -1)
    let v = String(p[vIndex...endIndex])
    return (u, v)
} 

func checkIsRightStr(_ str: String) -> Bool {
    var stack: [String] = []
    let strArr = Array(str).map{ String($0) }
    stack.append(strArr[0])
    for i in 1..<strArr.count {
        let currentStr = strArr[i]
        if currentStr == "(" {
            stack.append("(")
        } else {
            if !stack.isEmpty {
                let last = stack.last!
                if last == "(" {
                    stack.removeLast()
                } else {
                    return false
                }
            } else {
                return false
            }
        }
    }
    
    return stack.isEmpty
}

func reversedStr(_ p: String) -> String {
    var result = ""
    for str in Array(p) {
        if str == "(" {
            result.append(")")
        } else {
            result.append("(")
        }
    }
    return result
}

func solution(_ p:String) -> String {
    var answer = ""
    let pArr = Array(p)
    if p.count == 0 {
        return ""
    }
    if checkIsRightStr(p) {
        return p
    }
    //문자열 분리
    let splitStr = splitBalanceStr(p)
    let u = splitStr.0
    let v = splitStr.1
    //분리한 문자열 u가 완전한 문자열인지 체크
    if checkIsRightStr(u) {
        answer = u+solution(v)
    } else {
        answer += "("
        answer += solution(v)
        answer += ")"
        var removedU = u
        removedU.removeFirst()
        removedU.removeLast()
        answer += reversedStr(removedU)
    }
    
    return answer
}