华子目录
两两交换链表中的节点

思路
- 使用
虚拟头结点(要操作连续的两个节点,就必须找到其上一个节点),cur指向该节点 - 在交换之前,先对
虚拟节点.next和虚拟节点.next.next.next做临时记录 - 如果为
偶数个节点,则cur.next==None - 如果为
奇数个节点,则cur.next.next==None
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]:
virtualHead = ListNode()
virtualHead.next = head
cur = virtualHead
while cur.next != None and cur.next.next != None: # 这里得先判断cur.next != None,不然如果cur.next为None的话,那么cur.next.next就空指针溢出了
temp1 = cur.next
temp2 = cur.next.next.next
cur.next = cur.next.next
cur.next.next = temp1
cur.next.next.next = temp2
cur = cur.next.next
return virtualHead.next
删除链表的倒数第N个节点

思路
删除第N个节点,那么我们当前遍历的指针一定要指向第N个节点的前一个节点- 使用
虚拟头结点和left,right双指针,初始时,两个指针都指向虚拟头节点 right指针先向后移动N次,之后,双指针一起向后移动,当right为None时,left刚好指向倒数第N个节点- 所以
right指针一开始向后移动N+1次,这样left就可以指向被删除节点的前一个节点
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]:
virtualHead = ListNode()
virtualHead.next = head
left = right = virtualHead
while n+1>0:
right = right.next
n -= 1
while right != None:
right = right.next
left = left.next
left.next = left.next.next
return virtualHead.next
链表相交

思路1
- 先遍历出
A和B的各个长度lengthA和lengthB - 计算出
差值temp 最长的从头开始向后遍历temp次- 然后
curA和curB进行判断,如果相等则返回该节点,如果遍历完了还不相等则返回None
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:
curA, curB = headA, headB
lengthA = lengthB = 0
while curA:
lengthA += 1
curA = curA.next
while curB:
lengthB += 1
curB = curB.next
if lengthA > lengthB:
temp = lengthA - lengthB
curA, curB = headA, headB
while temp:
curA = curA.next
temp -= 1
while curA:
if curA == curB:
return curA
curA = curA.next
curB = curB.next
return None
else:
temp = lengthB - lengthA
curA, curB = headA, headB
while temp:
curB = curB.next
temp -= 1
while curA:
if curA == curB:
return curA
curA = curA.next
curB = curB.next
return None
思路2
- 使用
集合先记录一条链表的所有内存地址(哈希表) - 再去
遍历另一条链表,每遍历一个节点,就判断该节点的内存地址在不在集合中 - 如果
在就返回该节点,不在则返回None
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:
curA, curB = headA, headB
hash1 = set()
while curA:
hash1.add(curA)
curA = curA.next
while curB:
if curB in hash1:
return curB
curB = curB.next
return None
环形链表II

思路
- 使用
left,right快慢指针,两个指针第一次相遇时一定在环中,相遇前,left每次移动一个节点,right每次移动两个节点

- 当
left,right再次相遇时,就是入环口
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]:
left = right = head
while right and right.next: # right不为None,right.next也不为None
left = left.next
right = right.next.next
if left == right:
left = head
while left != right:
left = left.next
right = right.next
return left
return None