LeetCode-回文链表_进阶

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

O(1)的空间复杂度是一个限制性很强的条件,因此我们无法采用数组等存储链表的值后再进行判断。递归本来就属于调用栈,因此递归方法判断也被排除。

我们思考如何判断数组是否为回文串?可以设置两个指针,一个指向数组开始,一个指向数组结尾,依次向中间靠拢来判断是否是回文串。链表由于存在单向访问,无法直接像数组那样方便的用双指针法来判断。如果我们可以对链表也使用双指针法,那么就能满足空间复杂度为O(1)的要求。由于回文串可分为前半部分和后半部分,那么如果我们把链表的后半部分反转后,就能利用双指针,同时移动进行判断是否为回文串。根据这个思路,得到算法:

1、找到链表后半部分的开始节点pHeadSecondHalf;

2、反转以pHeadSecondHalf作为头节点的链表,得到反转后链表的头结点为pHeadReverseSecond;

3、利用双指针,一个指向前半部分开始节点,另一个指向pHeadReverseSecond;

4、判断双指针指向节点的值是否相等。如果相等,双指针同时向后移动,如果不相等,返回False;

5、重复步骤4,直到步骤四返回False或者双指针有一个指向空。

 

具体代码实现如下所示:

# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution(object):
    def isPalindrome(self, head):
        if head==None or head.next==None:
           return True
        
        pSecondHalfHead = self.firstHalfEnd(head).next
        
        pSecondHalfHead = self.reverseList(pSecondHalfHead)

        return self.isEq(head, pSecondHalfHead)

    def firstHalfEnd(self, head):
        pFast = head
        pSlow = head

        while pFast.next!=None and pFast.next.next !=None:
            pFast = pFast.next.next
            pSlow = pSlow.next
        return pSlow

    def isEq(self, headOne, headTwo):
        while headOne!=None and headTwo!=None:
            if headOne.val!=headTwo.val:
                return False
            headOne = headOne.next
            headTwo = headTwo.next
        return True
        
    def reverseList(self, head):
        pPrev = None
        pCur = head
        while pCur != None:
            pTmpNext = pCur.next
            pCur.next = pPrev

            pPrev = pCur
            pCur = pTmpNext

        return pPrev

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值