24. 两两交换链表中的节点
题目链接
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
视频讲解
帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点_哔哩哔哩_bilibili
笔记
- 为方便处理,新建虚拟头节点
- 遍历的变量cur为要处理节点的前一个
- 画图演示,将要用但是要更改的值先存在临时变量中
Python代码
# 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):
tmp = cur.next #先把后面需要用但即将要更改的节点保存下来
tmp2 = cur.next.next.next
cur.next = cur.next.next
cur.next.next = tmp
tmp.next = tmp2
cur = tmp # cur永远指向要处理的前一个
return dummy_head.next
19.删除链表的倒数第N个节点
题目链接
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
视频讲解
链表遍历学清楚! | LeetCode:19.删除链表倒数第N个节点_哔哩哔哩_bilibili
笔记
- 新建虚拟头节点
- 右指针初始化为虚拟头节点,先向右走n步
- 左指针初始化为虚拟节点,此时左右指针相差n步
- 同时向右移动左右指针,直到右指针指向链表最后一个节点,此时距离为n的左指针指向倒数第n+1个节点
- 修改左指针的next,即可实现删除链表倒数第n个节点的功能
Python代码
# Definition for singly-linked list.
# 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_head = ListNode(next = head)
r = dummy_head
for i in range(n): # 右指针先走n步
r = r.next
l = dummy_head # 左右指针距离相差n步
while r.next != None: #左右指针一起走
l = l.next
r = r.next
# 当右指针的next为None,也就是右指针指到最后一个节点的时候,左指针距离为n,
# 也就是左指针指向倒数第n+1个节点。此时修改左指针的next即可实现删除倒数第n个节点
l.next = l.next.next
return dummy_head.next
面试题 02.07. 链表相交
题目链接
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
视频讲解
笔记
- 若是两个链表长度相等,那思路是两个指针同时遍历链表,遇到指针相等则找到了相交节点
- 但此题链表长度不一定相等,那就想办法构造相等:若两个链表的长度分别为a和b,那么a+b是等于b+a的,也就是我们可以让指针遍历的时候从一个指针遍历结束跳到另一个指针,这样两个指针要遍历的总长度就是相等的,都是a+b
Python代码
# 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:
p1 = headA
p2 = headB
while p1 != p2:
if p1:
p1 = p1.next
else:
p1 = headB
if p2:
p2 = p2.next
else:
p2 = headA
return p1
142.环形链表II
题目链接
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
视频讲解
把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II_哔哩哔哩_bilibili
笔记
- 核心思路是用快慢指针,定义一个快指针每次走两步,一个慢指针每次走一步,如果快慢指针相遇则说明有环
- 判断有环之后,再定义两个指针,一个指向链表头部,一个指向相遇的节点,两个指针同时出发,每次走一步,两指针相遇的地方则为环的入口
- 注意处理特殊情况:当输入链表为空时直接返回None
Python代码
# 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]:
slow = head
fast = head
if head == None:
return None
while fast.next != None and fast.next.next != None:
slow = slow.next
fast = fast.next.next
if fast == slow: #判断相遇
tmp1 = head
tmp2 = fast
while tmp1 != tmp2: #判断环的入口
tmp1 = tmp1.next
tmp2 = tmp2.next
return tmp1
return None