【Leetcode每日一题】234. 回文链表 (异或法求解,空间复杂度O(1), 时间复杂度O(n))

Leetcode 每日一题
题目链接: 234. 回文链表
解题思路: 使用异或的性质,对于一个数a, 对他自己进行异或,值为0。不难得出:a ^ x ^ a = x 。有了上述的定理,我们可以将整个给定的链表节点值加上位置信息(可以自己设计Hash, 本文直接采用与中间位置的距离与链表节点的值的和)中的值进行异或,若最后的值等于0或者中间的值,那么他一定是回文串。
定义哈希函数为: Hash(node) = node.val + (position - len_list/2)
比如(support为辅助变量,进行异或计算)对于回文串: [1,5,3,5,1]
对于每一个节点:

						 H(0) = 3, support = 3
						 H(1) = 6,support = 3^6 = 5
						 H(2) = 3,support = 3^6^3 = 6
						 H(3) = 6,support = 3^6^3^6 = 0
						 H(4) = 3,support = 3^6^3^6^3 = 3

根据上述的例子很容易得出结论。
时间复杂度为O(n) 常数项有点高,因为需要额外计算一次链表长度;空间复杂度为O(1)。
题解:

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

class Solution:

    def isPalindrome(self, head: ListNode) -> bool:
        list_len = -1
        node = head
		
		# 计算链表长度
        while node != None:
            list_len += 1
            node = node.next

        # 长度为1 或 0
        if list_len == 0 or list_len == -1:
            return True

        node = head 
        # support 为辅助计算异或的变量,index为位置信息,mid_val 表示链表长度为奇数时的中间值。
        support, index, mid_val = 0, 0, 0
        while node != None:
            val = int(abs(index - (list_len/2))) + node.val
            # 异或叠加
            support ^= val
            if index == int(list_len/2):
                mid_val = node.val
            # print(val, support)

            node = node.next
            index += 1
        # 偶数个数
        if (list_len + 1) % 2 == 0 and support == 0:
            return True
        # 奇数个数
        if (list_len + 1) % 2 == 1 and support == mid_val:
            return True
        return False
        
    

猜你喜欢

转载自blog.csdn.net/qq_37753409/article/details/109247823