链表主题:
1. 反转链表 K个一组反转链表 - 灵神视频总结-CSDN博客
本节课主要讲 快慢指针在链表中的应用。
快慢指针 、 哨兵节点经常使用。
解法:
- 设置两个指针,快慢指针, slow fast, slow 移动一步, fast 移动两步。
- 根据题意来看,链表的长度有奇数偶数之分。如果是偶数的话,需要返回第二个节点。
- 那我们什么时候停止呢
-
- 当链表长度是奇数的时候,fast.next is None
- 当链表长度为偶数的时候,fast is None
- 总上所述,判断条件应该是 while fast.next and fast
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head.next :
return head
slow = fast = head
#. 1 -> 2 -> 3 -> 4 -> 5 奇数情况,fast.next is None
# 1 -> 2 -> 3 -> 4 -> 5 -> 6 偶数情况,fast is None
while fast and fast.next: # 经常搞不懂为什么到底是fast 还是 fast.next ,我们需要分情况讨论分析。
slow = slow.next
fast = fast.next.next
return slow
解法:
这题同样适用快慢指针来做,和上一题一样设置两个指针,slow 一次走一步,fast 一次走两步, 如果存在换的话, fast 相对slow的速度是1, 总可以相遇的,类似于slow在原地,fast一次走一步。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if not head or not head.next:
return False
slow = head
fast = head
while fast and fast.next : # fast 走两步,如果fast.next 为空的话, 空指针异常了。
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
这里有个结论,当快慢指针相遇时,慢指针还没有走完一整圈。
意味着: 当slow节点从相遇节点出发,经过c步+n次环长,正好和head节点从头出发,在进入环节点正好相遇。
当慢指针最坏的情况, fast 指针先slow一步,那么要走环长-1步才能相遇。其他情况都比这个要少。 所以时间复杂度是O(n)
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
while slow is not head :
slow = slow.next
head = head.next
return slow
return None
解法:
- 找到中间节点,把链表分成两部分。
- 反转后面的链表。
- 把链表拼接起来就好了。
-
- 这一步还有点绕,假设前面两步已经走完了, 1 -> 2 -> 3 -> 4 => 1 -> 2 -> 3 <- 4 3-> none
- 分别两头开始遍历,设置一个node1 = head, node2 ->4 , 先保存下下个节点, 2 和 3 , 让1 -> 4, 4->2 , 然后移动两个指针,node1 移动到2 , node2移动到3, 在什么时候停止呢,也就是node2 移动到3 的时候。node3.next 为空。
- 当然这一步也可以写一个函数来实现。
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution(object):
def findMid(self, head):
slow , fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
def reverse(self, head):
pre = None
cur = head
while cur :
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
return pre
def reorderList(self, head):
"""
:type head: ListNode
:rtype: None Do not return anything, modify head in-place instead.
"""
node1 = head
mid = self.findMid(head)
node2 = self.reverse(mid)
while node2.next:
nxt1 = node1.next
nxt2 = node2.next
node1.next = node2
node2.next = nxt1
node1 = nxt1
node2 = nxt2
def print_linked_list(self, head):
current = head
while current:
print(current.val, end=" -> ")
current = current.next
print("None")
def convert_list_to_link_list(self, array):
dummy = ListNode(-1)
cur = dummy
for val in array:
cur.next = ListNode(val)
cur = cur.next
return dummy.next
s = Solution()
a = [1,2,3,4]
a_head = s.convert_list_to_link_list(a)
res = s.reorderList(a_head)
s.print_linked_list(a_head)
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution(object):
def oddEvenList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head :
return head
evenHead = head.next
odd, even = head, evenHead
while even and even.next :
odd.next = even.next
odd = odd.next
even.next = odd.next
even = even.next
odd.next = evenHead
return head
def print_linked_list(self, head):
current = head
while current:
print(current.val, end=" -> ")
current = current.next
print("None")
def convert_list_to_link_list(self, array):
dummy = ListNode(-1)
cur = dummy
for val in array:
cur.next = ListNode(val)
cur = cur.next
return dummy.next
s = Solution()
a = [1,2,3,4]
a_head = s.convert_list_to_link_list(a)
res = s.oddEvenList(a_head)
s.print_linked_list(res)
补充题
你能做出这道题么?