알고리즘/알고리즘 문제풀이
Stack_프로그래머스_괄호 회전하기 [swift]
Downey
2022. 5. 11. 19:38
https://programmers.co.kr/learn/courses/30/lessons/76502?language=swift#
코딩테스트 연습 - 괄호 회전하기
programmers.co.kr
잘못된 접근 방법
- in 0..<s.count, s를 왼쪽으로 i 만큼 이동하면서 i 번 반복. 이 때, 왼쪽으로 이동한 글자는 오른쪽에 붙는다.
- 이동한 각 문자열에 대해서, recursion 실행.
- recursion > 열린 괄호와 매칭되는 첫번째 닫힌 괄호를 찾는다.
- 이 때, 닫힌 괄호가 endIndex라면, ( ??? ) 형태라고 생각하여, ???에 대하여 recursion을 재귀실행.
- endIndex가 아니라면, 닫힌 괄호를 기준으로 좌항과 우항으로 나누어 recursion실행, 결과값을 Boolean And하여 return. recursion 종료 >
- return true 횟수를 return 한다.
반례, {{{}}}() > {{{} }}()로 나뉜다. 마지막 괄호를 찾으면 되지 않는가 했는데, [](())[] > ](())[ 이 되므로 실패.
진짜 접근 방법
- in 0..<s.count, s를 왼쪽으로 i 만큼 이동하면서 i 번 반복. 이 때, 왼쪽으로 이동한 글자는 오른쪽에 붙는다.
- 이동한 각 문자열에 대해서, recursion 실행.
- recursion > 열린 괄호의 경우 stack에 넣는다.
- 닫힌 괄호의 경우, stack이 비어있지 않다면, 마지막 element가 대응하는 형태인지 확인, 틀리다면 return false
- stack이 비어있다면 return false
- 반복이 끝났을 때, return stack.isEmpty 하여, 혹시 모를 stack이 남는 경우까지 고려. recursion 종료>, 이 방법을 쓰면서 recursion이 아니게 되었다.
- return true 횟수를 return한다.
정답코드
정답은 recursion(:),
처음에 했던 오답은 recursion2(:)
더보기
class programmers_괄호회전하기 {
func solution(_ s: String) -> Int {
let movesLength = s.count
var sol = 0
for i in 0..<movesLength {
let target = wrapAroundLeft(text: s, howMany: i)
if recursion(text: target) {
sol += 1
}
}
return sol
}
func wrapAroundLeft(text: String, howMany n: Int) -> String {
let cuttingIndex = text.index(text.startIndex, offsetBy: n)
return String(text[cuttingIndex...] + text[text.startIndex..<cuttingIndex])
}
func recursion2(text: String) -> Bool {
if text.count % 2 == 1 {
return false
}
guard let first = text.first else {
return true
}
var second : Character
switch first {
case "(":
second = ")"
case "{":
second = "}"
case "[":
second = "]"
default:
return false
}
guard let isSecond = text.first(where: {$0 == second}) else {
return false
}
if text.count == 2 {
return true
}
guard let headPairIndex = text.firstIndex(of: isSecond) else {
return false
}
guard let tailPairIndex = text.lastIndex(of: isSecond) else {
return false
}
let pairIndexNext = text.index(after: headPairIndex)
if pairIndexNext == text.endIndex {
let result = recursion(text: String(text[text.index(after: text.startIndex)..<headPairIndex]))
print(text,String(text[text.index(after: text.startIndex)..<headPairIndex]), result)
return result
}
print(text,
String(text[..<pairIndexNext]),recursion(text: String(text[..<pairIndexNext])),
String(text[pairIndexNext...]),recursion(text: String(text[pairIndexNext...])))
guard recursion(text: String(text[..<pairIndexNext])) &&
recursion(text: String(text[pairIndexNext...])) else {
return false
}
return true
}
func recursion(text: String) -> Bool {
var stack = [Character]()
var sol = false
if text.count % 2 == 1 {
return false
}
for str in text {
if str == "(" ||
str == "{" ||
str == "[" {
stack.append(str)
} else if !stack.isEmpty {
switch stack.removeLast() {
case "(":
if str != ")" {
return false
}
case "{":
if str != "}" {
return false
}
case "[":
if str != "]" {
return false
}
default:
return false
}
} else {
return false
}
}
return stack.isEmpty
}
}