Given a strings, determine if it is a palindrome,
considering only alphanumeric characters and ignoring cases.
간단한 문제라 그냥 풀었지만 문득 내가 풀었던 방법 외에 다른 방법은 어떤 식이 있는지에 대해 궁금함이 생겼다. 먼저 내가 썼던 코드이다.
def isPalindrome(self, s: str) -> bool:
remove_specialized = "".join([x.lower() for x in s if x.isalnum()])
return remove_specialized == remove_specialized[::-1]
매개변수 `s`로 전달된 값을 반복문을 돌리면서 isalnum()을 이용하여 특수문자이면 결과가 False가 되니 이를 제외한 문자만 뽑은 다음 remove_specialized 변수에 바인딩하고 역순인 문자와 비교해 값 자체가 동일하면 true를 그렇지 않으면 false를 리턴한다.
통과는 되겠지만 이 간단한 코드를 보고 있으니 다음과 같은 생각이 든다.
1. `정말 반복문을 돌린 다음 문자 하나하나가 특수문자인지 체크해봐야 하나?`
2. `반복문 안에서 문자 하나를 꺼내서 소문자로 만들어버리는 건 너무 비효율적인 거 같은데?`
3. `python의 슬라이싱은 새로운 객체를 생성하기 때문에 return 문에서 메모리 공간을 하나 더 차지하게 비교하는 게 맞는 걸까?`
3번은 그렇다 치더라도 1번과 2번은 효율적인 방법이 있을 거 같아 내가 처음 작성한 코드에서만 조금 다르게 변경했다. 우선 1번은 해결방법이 떠오르지 않아 2번 고민에 대한 해결만 해봤다.
remove_specialized = "".join([x for x in s if x.isalnum()]).lower()
return remove_specialized == remove_specialized[::-1]
실제로 lower가 어떻게 동작하는지는 몰라도 컴프리헨션 안에 있던 lower() 메서드를 밖으로 뺸 것만으로도 Runtime이
81 -> 44로 줄어든 건 확연히 더 좋은 코드이지 않나 싶다. 더 찾아보던 중 다음과 같은 코드를 사용할 수 있음을 알았다.
def isPalindrome(self, s: str) -> bool:
remove_specialized = "".join(filter(str.isalnum, s.lower()))
return remove_specialized == remove_specialized[::-1]
filter 함수에 동작을 넘겨버리는 코드 정도라고 설명하면 충분한 것 같다. 이 방법이 내가 고민했던 1번 방법에 대한 해결책인 느낌이 든다. 이 코드에 대한 결과는 다음과 같다.
40대였던 컴프리헨션을 사용한 방식보다 Runtime이 더 떨어졌지만 메모리 사용은 올라갔다. 여기까지의 결과로 보자면 어느 코드가 더 좋다는 결론은 못 내리지 않나 싶다. 시간(Time)을 효율적으로 쓸 거냐 공간(Space)을 효율적으로 쓸 거냐는 아마 상황에 따라 다르지 않을까 싶다
'Algorithm > LeetCode' 카테고리의 다른 글
[LeetCode] Two Sum (0) | 2021.10.03 |
---|---|
[Leet Code] longest-palindromic-substring (1) | 2021.09.29 |
[Leet Code] Group Anagrams (0) | 2021.09.26 |
[Leet Code] Reorder Data in Log Files (0) | 2021.04.21 |
LeetCode를 통해서 본 Python의 문자열 뒤짚기 (0) | 2021.04.20 |