一、两两交换链表中的节点
每两个节点交换一下。如果节点个数为奇数,则最后一个节点不用交换
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy_head = ListNode(next = head) #虚拟头节点
cur = dummy_head
"""指针的下一个为空(对应奇数),指针的下下一个为空(偶数)"""
while (cur.next!=None and cur.next.next !=None):
"""cur每次应该出现在两个被交换节点的前一个节点,如cur=dummy_head,在头节点之前"""
temp = cur.next # 在交换时,要保存1号节点和3号节点
temp1 = cur.next.next.next # 防止其节点丢失
cur.next = temp.next # 让虚拟指向2号 虚拟到1号断了 其他正常
temp.next.next = temp # 让2号指向1号 2号到3号断了
temp.next = temp1 # 让1号指向 3号 1号到2号断了
cur = cur.next.next # 在让cur 移到3号前
# 重复上述过程,循环
return dummy_head.next
二、删除链表的倒数第N个节点
借助两个指针,让快指针到达最后一个节点时,慢指针正好在被删节点前
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy_node = ListNode(next = head)
fast = dummy_node
slow = dummy_node
while (n and fast!=None): # 快指针先向前移动n个节点 ,并且非空
fast = fast.next
n-=1
"""让快、慢指针一起走,直到快指针到最后一个节点,快慢指针相差n个节点"""
while (fast.next!=None): # 这个判断条件,使得慢指针正好在被删除节点前一个节点
"""如果是while (fast!=None) 慢指针就落在了被删节点上"""
fast = fast.next
slow = slow.next
slow.next = slow.next.next # 删除操作
return dummy_node.next
三、链表相交
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
curA= headA
curB= headB
lenA = 0
lenB = 0
while (curA!=None): # 找到其长度
lenA+=1
curA = curA.next
while (curB!=None): # 找到其长度
lenB+=1
curB = curB.next
curA = headA # 重新赋值 让其回到头节点
curB = headB
if lenA > lenB: # 比较长度 后面的操作是基于lenA > lenB,统一条件,处理更方便
pass
else : # 在这种情况下,将两个单链表调换一下,使得lenA > lenB
lenA , lenB = lenB,lenA
headA , headB = headB,headA
curA,curB = curB,curA
"""这段操作使得A永远是长的"""
n = lenA - lenB
while n: # 先让curA移动n个节点 此时与curB(头节点)对齐了
curA = curA.next
n -= 1
while(curA): # 只要curA不为空
if curA != curB: # 如果节点不相等 同时移动 A 和 B
curA = curA.next
curB = curB.next
else:
return curA # 相等 则返回节点
return None # 如果curA为空了 退出循环,即没找到相等的 返回None
四、环形链表II
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast = head
slow = head # 双指针
while (fast!= None and fast.next!=None): # 这个是判断是否为环形
fast = fast.next.next # 快指针 不满足条件,退出循环,即不是环形
slow = slow.next
if fast == slow : #相遇的条件
index1 = head #从头开始移动
index2 = fast #从相遇点开始移动
while index1 != index2:
index1 = index1.next # 让其移动,最终会在节点相遇
index2 = index2.next
"""最终相等的点,即为进入环形的节点"""
return index1
return None # 不是环形
x = z 这是一个特解。简单理解。即x = index1.next ,z = index2.next