본문으로 바로가기

[LeetCode] Palindrome 고찰하기

category Algorithm/LeetCode 2021. 9. 12. 22:47
728x90
반응형


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)을 효율적으로 쓸 거냐는 아마 상황에 따라 다르지 않을까 싶다

 

728x90
반응형