반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

멋진 개발자가 되고 싶다

[125번]유효한 팰린드롬(Valid-palindrome) 본문

Algorithm Study/leetcode

[125번]유효한 팰린드롬(Valid-palindrome)

오패산개구리 2021. 6. 24. 16:22
728x90
반응형

'팰린드롬'이란 앞뒤가 똑같은 단어나 문장을 말한다. 예를 들어, 기러기나 AOA 같은?? 예가 안 떠오른다. 아무튼.

 

 

 

내가 직접 작성한 코드

 

1
2
3
4
5
6
7
8
class solution:
    def isPalindrome(s: str-> bool:
        string = ''.join(filter(str.isalnum, s))  # 문자열에서 특수문자 제거
        list_s = list(string) # 문자열 -> 리스트 변환
        for i in range(len(list_s) // 2):  # 앞뒤를 하나씩 비교
            if list_s[i] != list_s[len(list_s) - i - 1]:
                return False
        return True
cs

 

해설:

 

''.join(s)는 s의 요소들을 하나의 문자열로 묶는다.

여기서 s가 꼭 리스트일 필요는 없다.

(위의 경우 filter(str.isalnum, s)는 filter 객체)

 filter(조건 함수, 순회 가능한 데이터)는 순회 가능한 데이터 s가

조건 함수인 isalnum에 하나씩 들어가면서 조건 여부를 판별한다.

isalnum()은 문자열이 영어, 한글, 숫자일 경우 True, 그렇지 않으면 False를 리턴한다.

그 후 반복문을 이용하여 앞뒤 문자를 비교하였다.

 

RunTime : 36ms

 

 

 

 

 

** 다양한 풀이 **

 

 

1. 리스트로 변환

 

1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
    def isPalindrome(s: str-> bool:
    strs = []
    # 문자열 with 특수문자 -> 리스트 without 특수문자
    for char in s:
        if char.isalnum():
            strs.append(char.lower())
    # 팰린드롬 여부 판별
    while (len(strs) > 1):
        if strs.pop(0!= strs.pop():
            return False
    return True
cs
cs

 

해설:

 

s의 문자를 하나씩 isalnum() 함수로 영어,한글,숫자 여부를 체크하여

True면 만들어둔 리스트 strs에 소문자로 입력.

이후 팰린드롬 판별 과정에서 리스트의 pop()을 이용하여 리스트 맨 앞과 맨 뒤를 비교하는 식으로 진행한다.

 

RunTime : 280ms

 

 

 

 

 

2. 데크(Deque) 자료형을 이용한 최적화

 

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
    def isPalindrome(self, s: str-> bool:
        # 자료형을 deque로 선언
        strs = collections.deque()
        # 문자열 with 특수문자 -> 리스트 without 특수문자
        for char in s:
            if char.isalnum():
                strs.append(char.lower())
        # 팰린드롬 여부 판별
        while (len(strs) > 1):
            if strs.popleft() != strs.pop():
                return False
        return True
cs

 

해설:

 

1번 풀이에서 자료형을 리스트가 아닌 deque로 선언해주고

팰린드롬 여부 판별에서 strs.pop(0)이 아닌 strs.popleft()를 사용하였다.

하지만 런타임은 6배 정도의 차이를 보였다.

그 이유는 리스트는 que인데 pop(0)이 O(n)인데 반해, deque는 popleft()가 O(1)이기 때문이다.

각각 n번씩 반복하면 O(n^2), O(n)으로 성능 차이가 크다.

 

RunTime : 48ms

 

 

 

 

 

3. 슬라이싱 사용

 

1
2
3
4
5
6
7
class Solution:
    def isPalindrome(self, s: str-> bool:
        s = s.lower()
        # 정규식으로 불필요한 문자 필터링
        s = re.sub('[^a-z0-9]''',s)
 
        return s == s[::-1# 슬라이싱
cs

 

해설:

 

문자열 s에서 대문자를 소문자로 바꿔준 다음

정규표현식으로 불필요한 문자를 필터링하였고

마지막으로 s와 뒤집은 s를 비교한 결과를 리턴하였다.

 

 

정규표현식:

 

특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어.

a-z는 a, b, c,,, z를 의미하고 0-9는 0,1,2,,,9를 의미한다.

 

[]는 '대괄호 안에 포함된 문자들 중 하나와 매치'를 뜻한다.

[] 안에 있는 ^는 '반대'의 의미를 담고 있다.

 

따라서 [^a-z0-9]를 해석하면 나'a~z, 0~9가 아닌 문자들 중 하나'이다.

 

즉, s = re.sub('[^a-z0-9]', '', s)는

문자열 s에서 문자마다 특수문자이면 ''으로 대체하겠다는 의미이다.

 

 

 

 

 

 

 

출처 : 파이썬 알고리즘 인터뷰 (글 : 박상길 그림 : 정진호) [책만]

728x90
반응형