24. 两两交换链表中的节点
思路:
# 常规操作
1. 首先链表为空,链表只有一个:返回自己即可
2. 设置虚拟头节点,简化流程
# 开始迭代
反转链表需要:前面的节点,现在的节点,后面的节点;
反转完后,更新前面的节点,现在的节点,后面的节点。
何时结束循环:现在的节点不存在(偶数个nodes会遇到)/后面的节点不存在(奇数个nodes会遇到)时,就停止。
# 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]:
# if the list only have 1 or no node, return itself
if not head or not head.next:
return head
# the dummy node for the list (q.back)
p = ListNode(0, head)
# q and q.next are nodes to swap everytime
q = p.next
# define the new head
new_head = head.next
# q should always have a node to swap with(odd numbers); also q should exist(even numbers)
while q and q.next:
r = q.next
s = q.next.next
# swap q and q.next(r); q.back -> q.next
p.next = r
r.next = q
q.next = s
# define the new q and q.back
p = q
q = q.next
return new_head
19.删除链表的倒数第N个节点
# 非常显然,快慢指针 -> 减少一次循环
# 和《长度最小的子数组》使用一种方法
# 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]:
# 使用快慢指针
# 使用头节点可以优化删除头节点的逻辑
dum = ListNode(next=head)
l1, l2 = dum, dum
for _ in range(n):
l1 = l1.next
# while p.next 可以达到最后一个, 但不操作了
# while p 可以到达空节点,但是下次循环不操作了
while l1.next:
l2 = l2.next
l1 = l1.next
l2.next = l2.next.next
return dum.next
面试题 02.07. 链表相交
# 思路:链表1、链表2各跑一遍,确定长度差。
# 长的那个先跑几步(弥补长度差),再同时出发,必定会相遇。否则无交点。
# 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) -> Optional[ListNode]:
length_a, length_b = 0, 0
node_a = headA
node_b = headB
while node_a:
length_a += 1
node_a = node_a.next
while node_b:
length_b += 1
node_b = node_b.next
if length_b > length_a:
headA, headB = headB, headA
length_a, length_b = length_b ,length_a
for _ in range(length_a-length_b):
headA = headA.next
while headA != headB:
headA = headA.next
headB = headB.next
return headA
142.环形链表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
slow2 = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
while slow != slow2:
slow = slow.next
slow2 = slow2.next
return slow2
return None