[Gold V] 회문 - 17609
성능 요약
메모리: 83984 KB, 시간: 724 ms
분류
문자열, 두 포인터
문제 설명
회문(回文) 또는 팰린드롬(palindrome)은 앞 뒤 방향으로 볼 때 같은 순서의 문자로 구성된 문자열을 말한다. 예를 들어 ‘abba’ ‘kayak’, ‘reviver’, ‘madam’은 모두 회문이다. 만일 그 자체는 회문이 아니지만 한 문자를 삭제하여 회문으로 만들 수 있는 문자열이라면 우리는 이런 문자열을 “유사회문”(pseudo palindrome)이라고 부른다. 예를 들어 ‘summuus’는 5번째나 혹은 6번째 문자 ‘u’를 제거하여 ‘summus’인 회문이 되므로 유사회문이다.
여러분은 제시된 문자열을 분석하여 그것이 그 자체로 회문인지, 또는 한 문자를 삭제하면 회문이 되는 “유사회문”인지, 아니면 회문이나 유사회문도 아닌 일반 문자열인지를 판단해야 한다. 만일 문자열 그 자체로 회문이면 0, 유사회문이면 1, 그 외는 2를 출력해야 한다.
입력
입력의 첫 줄에는 주어지는 문자열의 개수를 나타내는 정수 T(1 ≤ T ≤ 30)가 주어진다. 다음 줄부터 T개의 줄에 걸쳐 한 줄에 하나의 문자열이 입력으로 주어진다. 주어지는 문자열의 길이는 3 이상 100,000 이하이고, 영문 알파벳 소문자로만 이루어져 있다.
출력
각 문자열이 회문인지, 유사 회문인지, 둘 모두 해당되지 않는지를 판단하여 회문이면 0, 유사 회문이면 1, 둘 모두 아니면 2를 순서대로 한 줄에 하나씩 출력한다.
풀이
투 포인터로 문제입니다.
만약 양 옆의 값이 다를 때, 해당 범위 안에 있는 문자열이 회문인지 확인하여 만약 회문이라면 유사 회문을 반환합니다.
이미 다른 값이 나왔기 때문에 해당 범위(시작점~끝점)에서 다른 문자가 나온다면 유사 회문도 아니게 됩니다.
(한 문자만 다를 경우에 유사회문)
import Foundation
// check = 0: 회문 판단, check = 1: 유사회문 판단
func palindrome(_ s: String, _ check: Int) -> Int {
var left = 0
var right = s.count - 1
let sArray = Array(s)
while left < right {
if sArray[left] != sArray[right] { // 값이 다를 때
if check == 0 {
// 유사 회문인지 판단
let len = right - left
if palindrome(String(sArray[left + 1...left + len]), 1) == 0 || palindrome(String(sArray[left...left + len - 1]), 1) == 0 {
// left + 1부터 right까지나 left부터 right - 1까지(확인되지 않은 부분들)가 회문이라면
return 1 // 유사 회문
} else {
return 2 // 유사 회문이 아님
}
} else { // 한 문자를 이미 삭제했기 때문에(유사회문) 이 경우에는 무조건 될 수 없음
return 2
}
}
// 값이 같다면
left += 1
right -= 1
}
return 0
}
if let T = Int(readLine()!) {
for _ in 0..<T {
if let s = readLine() {
print(palindrome(s, 0))
}
}
}
'PS > BOJ' 카테고리의 다른 글
[백준(BOJ)] 2467 용액 - 스위프트(Swift) (0) | 2023.08.30 |
---|---|
[백준(BOJ)] 22945 팀 빌딩 - 스위프트(Swift) (0) | 2023.08.30 |
[백준(BOJ)] 1806 부분합 - 스위프트(Swift) (0) | 2023.08.28 |
[백준(BOJ)] 3273 두 수의 합 - 스위프트(Swift) (0) | 2023.08.28 |
[백준(BOJ)] 1863 스카이라인 쉬운거 - 스위프트(Swift) (0) | 2023.08.28 |