https://programmers.co.kr/learn/courses/30/lessons/12973?language=swift
문자열 2개가 연속으로 같을 경우 제거해주며, 문자열을 모두 제거할 수 있는지 없는지 판단하는 문제.
문자를 앞에서 부터 하나하나 이전 요소와 비교해줄 필요가 있기에 Stack의 개념을 활용하면 쉽게 풀이할 수 있다.
문제의 예시처럼 문자열이 "baabaa" 일 경우, stack에는 아래와 같이 쌓이고 제거된다.
b > b a > b a a > b b > a > a a
이 경우 모든 원소가 사라지기 때문에 1을 리턴해주면 된다. 불가할 경우는 0 리턴!
아래 프로세스를 먼저 봐보자.
1. 총 길이가 홀수인 경우는 모든 원소가 절대 다 사라질 수 없음. 그렇기에 예외 처리
2. Stack(result)과 원소를 가져올 배열(str)을 만들어준다.
3. idx를 돌며 result의 마지막 값과 비교하며 추가/삭제 해준다.
4. 그 다음 원소로 이동하며 3번 내용을 계속 점검한다.
if let을 사용하는 풀이와 guard let을 사용하는 풀이 모두 진행해보았는데
크게 효율차이는 없어보인다! 왜냐... 구성 코드가 동일하기 때문인듯 싶다!
이제 코드를 봐보자.
import Foundation
func solution(_ s:String) -> Int{
// index 접근하기 위해 배열로 바꿔준다.
var str = s.map { String($0) }
// 결과를 담을 Stack
var result = [String]()
var idx = 0
// 총 길이가 홀수면 어떻게 해도 다 사라지지 못한다.
if str.count % 2 != 0 { return 0 }
// 처음 원소 붙이고 시작
result.append(str.removeFirst())
// idx가 str의 길이보다 크면 안됨
while idx < str.count {
// result의 마지막 원소가 존재한다면
if let last = result.last {
// result의 마지막 원소와 다음에 들어올 원소가 같다면
if last == str[idx] {
// result의 마지막 삭제
result.removeLast()
} else {
// 다르다면 다음 원소 result에 추가
result.append(str[idx])
}
} else {
// result가 비어있다면 값 추가
result.append(str[idx])
}
// 다음 원소로 이동
idx += 1
}
return result.count == 0 ? 1 : 0
}
위 프로세스를 따르는 풀이이다.
참고용으로 guard문 사용한 케이스도 올려본다! 보기에 코드가 조금 더 깔끔한 느낌..?이 있다.
import Foundation
func solution(_ s:String) -> Int{
// index 접근하기 위해 배열로 바꿔준다.
var str = s.map { String($0) }
// 결과를 담을 Stack
var result = [String]()
var idx = 0
// 총 길이가 홀수면 어떻게 해도 다 사라지지 못한다.
if str.count % 2 != 0 { return 0 }
// 처음 원소 붙이고 시작
result.append(str.removeFirst())
while idx < str.count {
let next = str[idx]
guard let last = result.last else { result.append(next); idx += 1; continue }
if last == next {
result.removeLast()
} else {
result.append(next)
}
idx += 1
}
return result.count == 0 ? 1 : 0
}
그리 어려운 문제는 아니었다.
다만 문제를 보고 여러 자료구조를 떠올릴 수 있도록 계속 반복 학습을 해야겠다.
끄읕