Leetcode日练笔记32 [Linked List专题] #328 #234 Odd Even Linked List & Palindrome Linked List

这篇博客讨论了两种链表问题的解法。第一题是将链表中奇数位置的节点和偶数位置的节点分别链接在一起,保持内部顺序不变。解题策略涉及对链表的迭代和重新连接。第二题是判断链表是否为回文,通过双指针法找到链表中间点,然后反转后半部分并进行比较。博客探讨了两种方法的时间和空间复杂度,并分析了代码细节和不同实现之间的差异。
摘要由CSDN通过智能技术生成

#328 Odd Even Linked List

Given the head of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return the reordered list.

The first node is considered odd, and the second node is even, and so on.

Note that the relative order inside both the even and odd groups should remain as it was in the input.

You must solve the problem in O(1) extra space complexity and O(n) time complexity.

解题思路:

这题真的太难了……我一开始想的是swap第一个偶数和第二个奇数的操作。在接下去是第三个奇数(如果有的话)插到2前面然后2,4作为一个整体,4先连6,3再接2.

总的来说分为3步,1接3,2接4,再3接2。奇数相连,再偶数相连,再奇偶列相连。

但总是卡在第三步因为每次接连完奇偶列,最后都是要接回2.这变成要5个指针。不科学。写来写去都写不出来。

后来参考了solution。原来最后一步奇偶列相连可以不用每次循环都做一遍,我当初以为如果完全割裂开,等于space complexity需要存偶数列的数据,就达不到题目的要求。但solution解释,只要永远有个指针指着2,就不占内存。暂时理解不能,先放一下这里。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head: return head 
         
        odd, even, evenhead = head, head.next, head.next
        while odd.next and even.next:      # end condition is neither exists
            odd.next = even.next    # odd links together eg 1 links 3
            odd = odd.next          # odd pointer moves forward
            even.next = odd.next    # eg 2 links 4 or None
            even = even.next        # even pointer moves forward
        
        odd.next = evenhead
        return head

runtime:

再看了forum,除了end condition和上述的不同之外其他都一样。 就不研究了。

#234 Palindrome Linked List

Given the head of a singly linked list, return true if it is a palindrome.

解题思路:

要满足回文条件的话,而且space complexity只能是O(1),则一定有个指针指到尾。尾的那截要处理成reversed的linked list. 回顾206题,逆处理需要知道逆开始的头在哪里,再加上头之前的那个指针。要定位中间的指针,必须建立在尾指针的1/2的信息上,相当于fast走2n步,slow走n步。等到尾指针走到了None,才得到中间指针,也就是slow的位置之后,才能将逆处理要用到的prev用上。所以一共要三个指针。最后是头列和prev列点对点的值作对比,全部相等就返回true,反之则反。

# 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: Optional[ListNode]) -> bool:
        if not head.next:
            return True
        slow, fast, prev = head, head.next, None
        
        while fast and fast.next:    # end condition is fast landing on the last node
            fast = fast.next.next
            slow = slow.next
        
        slow = slow.next
        
        while slow:
            nxt = slow.next
            slow.next = prev
            prev = slow
            slow = nxt
            
        while head and prev:
            if head.val != prev.val:
                return False
            head = head.next
            prev = prev.next
        return True

runtime:

这里有个细节,我是犯了错的。在推进fast pointer的时候,我设置的end condition是fast.next.next必须要存在。但是error报错说Nonetype是没有next attribute的。当我参考了油管的Neetcode时,同样的目的,Neetcod写成了while fast and fast.next就可以达到。 这里不明白为什么fast.next就不会遇到AttributeError的问题。而且确保快指针慢指针往前走我设定的是fast的下两个点必须存在,但Neetcode和forum上的都是fast以及fast下个点在就可以了。

所以说,就是他们的思路是可以允许fast走到None上的,这个时候slow也自然在应该开始的位置。而我是不允许fast走出链表的,往前走不动就最后slow再往前走一步。思路的区别在这里。但为什么fast.next就不会出现AttributionError呢?难道说这里的fast是永远不可能为None?但当fast往前走两步之后,就可能会出现fast是None的情况啊,按他们while的条件是fast and fast.next的话,也应该会出现fast.next是AttributionError的情况啊不是么?无法理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值