环形链表–141
判断链表中是否存在环
链表定义:
class ListNode():
def __init__(self,x):
self.val=x
self.next=None
方法:快慢指针
fast和slow指针分别指向head节点,fast一次走两步,slow一次走一步,当fast和slow走进环后,
fast速度比slow快1步,会在环中与slow相遇。
def hasCycle(head: ListNode) ->bool:
slow = head
fast = head
while (fast!=None and fast.next!=None):
slow = slow.next
fast = fast.next.next
# 快慢指针相遇
if slow == fast:
return True
return False
环形链表–142
找到链表中环起点
方法:快慢指针
fast和slow指针分别指向head节点,fast一次走两步,slow一次走一步,当fast和slow走进环后,fast速度比slow快1步,会在环中与slow相遇。
此时假设slow走了k步,则fast走了2k步,假设环起点距离slow和fast m步,将slow再次指向head,放慢fast的速度为一步,当两节点相遇时即为环起点。slow,fast走了k-m步,k为环长度倍数,既想当于节点fast往回走了m步。
def hasCycle(head: ListNode) ->bool:
slow = head
fast = head
while (fast!=None and fast.next!=None):
slow = slow.next
fast = fast.next.next
# 快慢指针第一次相遇
if slow == fast:
break:
slow = head
while fast!=None and fast.next!=None:
slow =slow.next
fast =fast.next
if slow==fast:
return slow
反转链表
1.单链表反转
使用cur指向当前节点,使用pre指向前一节点,nex指向后一节点
- 记录后一节点nex=cur.next
- 使得当前节点cur指向pre,即反转当前节点
- cur,pre = nex,cur 节点往后移动
- 重复1-3,直到cur指向末尾节点的next=None
此时pre->末尾节点,cur,nex->None - 链表反转完成
def reverselist(head: ListNode) -> ListNode:
# 当链表为空或只有一个节点时
if head==None or head.next=None:
return head
cur = head
pre = None
nex = None
while cur!=None:
nex =cur.next
cur.next=pre
pre=cur
cur=nex
return pre
递归反转链表
def reverselist(head: ListNode) -> ListNode:
# 当head为空或者head为最后一个节点时,将head return
if head==None or head.next==None:
return head
new_head = reverselist(head.next)
head.next.next = head
head.next= None
return new_head
- 可以将reverselist(head.next)作为一个节点来看,用new_head记录
- 链表可以看成两个节点的链表,将head->next->next=head,即将head的下一个节点指向head
- 再将head->next=None
- new_head只会是head为最后一个节点时的return,即反转链表后的头结点
反转链表2
给定链表中两个节点left,right,反转两节点间的节点
使用头插法:
将left的下一个节点单独提出放在left前
将left.next==E.next,摘出节点E
E.next = left
C.next=E
将节点E插在节点left前
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
if head==None or head.next==None:
return head
# 用dummy记录头结点
dummy = ListNode()
dummy.next =head
pre = dummy
# pre 指针指向 left的前一节点,因为从dummy节点开始移动
for _ in range(left-1):
pre = pre.next
cur = pre.next
for _ in range(right-left):
temp = cur.next
cur.next = temp.next
temp.next = pre.next
pre.next = temp
return dummy.next