#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 andO(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, returntrue
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的情况啊不是么?无法理解。