[알고리즘] 팰린드롬 연결 리스트

June·2021년 1월 18일
0

알고리즘

목록 보기
23/260

팰린드롬 연결 리스트

내 풀이

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        tmp = []
        while head != None:
            tmp.append(head.val)
            head = head.next
        return tmp == tmp[::-1]

속도가 매우 느리게 나왔다.

책 풀이 1

    def isPalindrome(self, head: ListNode) -> bool:
        q: List = []
        
        if not head:
            return True
        
        node = head
        # 리스트 변환
        while node is not None:
            q.append(node.val)
            node = node.next
        
        # 팰린드롬 판별
        while len(q) > 1:
            if q.pop(0) != q.pop():
                return False
        return True

내 풀이와 마찬가지로 리스트를 이용하지만 초기 조건을 주었고, 또한 비교할 때 앞뒤로 하나씩 빼며 비교하였다.

책 풀이 2

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        q: Deque = []

        if not head:
            return True

        node = head
        # 리스트 변환
        while node is not None:
            q.append(node.val)
            node = node.next

        # 팰린드롬 판별
        while len(q) > 1:
            if q.popleft() != q.pop():
                return False
        return True

책 풀이 1에서 앞뒤로 뺀다는 점에 착안하여 덱을 쓰면 더욱 효율적이다.

책 풀이 3

    def isPalindrome(self, head: ListNode) -> bool:
        rev = None
        slow = fast = head
        # 런너를 이용해서 역순 연결 리스트 구성
        while fast and fast.next:
            fast = fast.next.next
            rev, rev.next, slow = slow, rev, slow.next

        # 홀수 개일 경우 가운데 값 처리
        if fast:
            slow = slow.next

        # 팰린드롬 여부 확인
        while rev and rev.val == slow.val:
            slow, rev = slow.next, rev.next
        return not rev

런너(Runner) 기법을 활용한 것이다. slow 런너와 faster 런너를 동시에 출발시키면 fast가 끝에 도착할 때 slow는 정확히 중간 지점에 도착한다. 느린 런너는 중간까지 가면서 역순으로 연결 리스트 rev를 만든다. 중간 지점에서 느린 런너가 끝까지 도착할 때, 역순으로 만든 연결 리스트와 일치하는지 확인하면 된다.

0개의 댓글

관련 채용 정보