Valid Palindrome

문제 링크

문제 설명

  • 주어진 문자열이 팰린드롬인지 확인
  • 대소문자를 구별하지 않음
  • 영문자와 숫자만을 대상으로 한다.
Example 1:

Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.

Example 2:

Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.

풀이 전략

  • 리스트로 변환
  • 데크 자료형을 이용한 최적화
  • 슬라이싱 사용
    • 이걸로 구현하는 것이 속도가 제발 빠름
class Solution:
    def isPalindrome(self, s: str) -> bool:
        s = s.lower() # 1. 문자열을 모두 소문자로 변환합니다.
        s = re.sub('[^a-z0-9]', '', s) # 2. 영문자와 숫자 이외의 문자를 제거합니다.
        return s == s[::-1] # 3. 문자열이 뒤집은 문자열과 같은지 확인합니다.

코드 분석

이 코드는 문자열이 회문(앞뒤가 같은 문자열)인지 확인하는 함수입니다. 대소문자를 구분하지 않고, 영문자와 숫자만 고려하여 회문을 판별합니다.

class Solution:
    def isPalindrome(self, s: str) -> bool:
        s = s.lower()                      # 1. 문자열을 모두 소문자로 변환합니다.
        s = re.sub('[^a-z0-9]', '', s)      # 2. 영문자와 숫자 이외의 문자를 제거합니다.
        return s == s[::-1]                 # 3. 문자열이 뒤집은 문자열과 같은지 확인합니다.

각 단계의 작동 방식을 더 자세히 설명하면 다음과 같습니다.

  1. 소문자로 변환:이 단계에서는 문자열 s를 모두 소문자로 변환하여, 대소문자 차이를 무시합니다. 예를 들어, 'RaceCar''racecar'로 변환됩니다.
  2. s = s.lower()
  3. 영문자와 숫자 외의 문자 제거:이 단계에서는 정규 표현식 re.sub('[^a-z0-9]', '', s)을 사용하여 영문자(a-z)와 숫자(0-9) 이외의 모든 문자를 제거합니다. 공백, 구두점, 특수 문자가 제거됩니다. 예를 들어, s = "A man, a plan, a canal: Panama"라면 이 과정 후 s"amanaplanacanalpanama"가 됩니다.
  4. s = re.sub('[^a-z0-9]', '', s)
  5. 회문 여부 확인:마지막 단계에서는 문자열 s와 뒤집은 문자열 s[::-1]이 같은지 확인합니다. 만약 같다면 True를 반환하고, 그렇지 않다면 False를 반환합니다. 이 비교는 문자열이 회문인지 여부를 판단합니다.
  6. return s == s[::-1]

예시

  • s = "A man, a plan, a canal: Panama"
    • 소문자로 변환 후: "a man, a plan, a canal: panama"
    • 영문자와 숫자만 남기면: "amanaplanacanalpanama"
    • 뒤집은 문자열과 비교: "amanaplanacanalpanama" == "amanaplanacanalpanama"이므로 True
  • s = "race a car"
    • 소문자로 변환 후: "race a car"
    • 영문자와 숫자만 남기면: "raceacar"
    • 뒤집은 문자열과 비교: "raceacar" != "raceacar"[::-1], 즉 "raceacar" != "raceacar"이므로 False

이 코드의 반환값은 주어진 문자열이 회문일 때 True, 그렇지 않으면 False입니다.