leetcode 234. palindrome-linked-list 回文链表 python3

时间:2020-07-04

题目地址:https://leetcode-cn.com/problems/palindrome-linked-list

题目难度:Easy

题目描述:

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

示例 1:

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

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


思路1:快慢指针,一半堆栈

代码段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:
        if head == None or head.next == None:
            return True
        if head.next.next == None:
            if head.val == head.next.val:
                return True
            else:
                return False
        slow, fast, temp = head, head, [head.val]
        while fast.next != None and fast.next.next != None:
            fast = fast.next.next
            slow = slow.next
            temp.append(slow.val)
        if fast.next == None:
            temp.pop()
        print(temp)
        while slow.next != None:
            slow = slow.next
            if slow.val == temp[-1]:
                temp.pop()
            else:
                return False
        if len(temp) == 0:
            return True
        else:
            return False

总结:

  1. 我写的太烂了,是得背代码了么
  2. 看下优化的
# 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:
        stack = []
        slow = head
        fast = head
        # step1: push
        while(fast and fast.next):
            stack.append(slow)
            slow = slow.next
            fast = fast.next.next
        if fast: # 奇数
            slow = slow.next
        # step2: pop and compare
        while(stack):
            curr = stack.pop()
            if curr.val != slow.val:
                return False
            slow = slow.next
        return True

思路2:快慢指针,反转

代码段2:通过

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        slow,fast,prev = head,head,None
        while fast is not None:
            slow = slow.next
            fast = fast.next.next if fast.next is not None else fast.next
        while slow is not None:
            slow.next, slow, prev= prev, slow.next, slow
        while head and prev:
            if head.val != prev.val:
                return False
            head = head.next
            prev = prev.next
        return True

总结:

  1. 牛,这道题也算简单,我累了= =

思路3:反转原始链表存入一条新的链表【2021-2-17】

代码段3:一个超时

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
import copy
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:    
        old = copy.deepcopy(head) # 链表的深复制,用于与反转后的链表比较
        print(old)
        temp = head
        def reverse(head):
            if head == None or head.next == None:
                return head
            new_head = reverse(head.next)
            head.next.next = head
            head.next = None
            return new_head
        
        new = reverse(temp)
        print(new)
    
        while new and old:
            if new.val != old.val:
                return False
            new = new.next
            old = old.next
        return True

总结:

  1. 对象赋值传递的是对象的引用,copy.copy() 浅拷贝,不会克隆子对象,copy.deepcopy()深拷贝,会克隆子对象

思路4:利用递归函数本身的堆栈实现倒序

代码段4:通过

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    left = ListNode()
    def isPalindrome(self, head: ListNode) -> bool:
        global left
        left = head
        def traverse(right):
            if right == None:
                return True
            res = traverse(right.next) //链表的后序遍历(倒序遍历链表)
            global left
            res = right.val == left.val and res
            left = left.next
            return res
        return traverse(head)

总结:

  1. 链表的前序遍历和后序遍历与二叉树一致,可实现顺序遍历 倒序遍历链表

思路5:利用快慢指针,回文的特殊性

代码段5:通过

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        slow, fast = head, head
        while fast != None and fast.next != None:
            slow = slow.next
            fast = fast.next.next # 快慢指针,找到链表中点
        if fast != None: 
            slow = slow.next # 长度为奇数,slow再往后一步

        def traverse(slow): # 反转链表
            pre, cur = None, slow
            while cur:
                nxt = cur.next
                cur.next = pre
                pre = cur
                cur = nxt
            return pre
        left = head
        right = traverse(slow) # 从slow开始反转,进行比较
        while right:
            if left.val != right.val:
                return False
            left = left.next
            right = right.next
        return True

总结:

  1. 这道题作为简单简直毫无天理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值