面试题 02.06. 回文链表

题目

编写一个函数,检查输入的链表是否是回文的。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true 

分析: 判断单链表是否是回文链表,及链表的正序等于反序,最容易想到的一种方式是复制一份相同的链表,进行反转后逐节点比较

方法一:复制链表进行反转比较

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

#先复制链表,再反转链表,比较两个链表是否相等
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        if head == None or head.next == None:
            return True
        new_head = ListNode(head.val)
        tmp_new_head = new_head
        tmp_head = head
        while tmp_head.next != None:
            tmp_head = tmp_head.next
            tmp_new_head.next = ListNode(tmp_head.val)
            tmp_new_head = tmp_new_head.next

        head_reverse = None
        cur_node = head
        while cur_node != None:
            tmp_node = cur_node.next
            cur_node.next = head_reverse
            head_reverse = cur_node
            cur_node = tmp_node
        while new_head != None and head_reverse != None:
            if new_head.val == head_reverse.val:
                new_head = new_head.next
                head_reverse = head_reverse.next
            else:
                return False
        return True

方法二:回文链表节点值基于中心点对称,因此可以找到链表的中心节点,然后反转后半部分链表,与前半部链表进行比较即可,需要注意链表奇偶长度的处理,此方法时间复杂度是O(n), 空间复杂度O(1)

class Solution1:
    def isPalindrome(self, head: ListNode) -> bool:
        if head == None or head.next == None:
            return True
        fast = head
        slow = head
        while fast != None and fast.next != None:
            slow  = slow.next
            fast = fast.next.next

        if fast != None:
            slow = slow.next
        # 反转slow后部分的链表,可以用遍历,也可以用递归
        '''
        new_head = None
        while slow != None:
            tmp_node = slow
            slow = slow.next
            tmp_node.next = new_head
            new_head = tmp_node
        '''
        #采用递归的方式反转链表
        new_head = self.reverse(slow)
        while new_head != None:
            if head.val != new_head.val:
                return False
            head = head.next
            new_head = new_head.next

        return True

    def reverse(self, head):
        if head.next == None:
            return head
        last_node = self.reverse(head.next)
        head.next.next = head
        head.next = None
        return last_node

方法三:借助二叉树的后序遍历操作,链表也可以进行,链表兼具递归结构,树结构不过是 链表的衍⽣,因此,可以通过递归的方式实现链表的后序遍历,实现后序遍历后便可以进行头节点和尾节点的双指针操作,模拟列表两端靠拢判断

#采用后续遍历
class Solution2:
    def isPalindrome(self, head: ListNode) -> bool:
        if head == None or head.next == None:
            return True
        head, judge = self.recursive(head, head)
        return judge

    def recursive(self, head, left):
        if left == None:
            return head, True
        head, judge = self.recursive(head, left.next)
        if head.val == left.val and judge:
            return head.next, judge
        else:
            return head, False
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值