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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章