- 虚拟头节点可以防止在链表头和链表尾部的不同规则,使得一个规则可以完成对头和中间的操作
- 注意and的逻辑
- 非常重要的是虚拟头节点和快慢指针
- 重回头节点也是非常重要的思路
24. 两两交换链表中的节点
感觉写的时候有点迷迷糊糊的,但是结果竟然对了
# 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]:
# 尝试使用创设的虚拟节点来进行互换
node0 = dummy = ListNode(next = head)
node1 = head
while node1 and node1.next:
node2 = node1.next
node0.next = node1.next
node1.next = node2.next
node2.next = node1
node0 = node1
node1 = node1.next
return dummy.next
注意and的逻辑:
- 在 Python 中,如果
node1
是尾节点(即node1
为None
),node1 and node1.next
不会报错。这是因为 Python 中的 and 运算符是短路运算符,它会在第一个条件为假时立即停止并返回假。 - 因此,如果
node1
是尾节点,条件node1 and node1.next
中的第一个条件node1
会被解释为假(False),然后 Python 将停止计算并返回假,而不会进一步检查node1.next
是否存在,也就不会报错。
19.删除链表的倒数第N个节点
利用了虚拟头节点进行运用,但是结果上还是要分类讨论是否重新定义了head
# 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]:
p = head
p_dele_before = ListNode(next = head)
i = 1
while p.next != None:
if i >= n:
p_dele_before = p_dele_before.next
p = p.next
i += 1
if i > n and i != 1:
p_dele_before.next = p_dele_before.next.next
return head
elif i == n and i != 1:
p_dele_before.next = p_dele_before.next.next
return p_dele_before.next
else:
return 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 removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
left = right = dummy = ListNode(next = head)
for _ in range(n):
right = right.next
while right.next:
left = left.next
right = right.next
left.next = left.next.next
return dummy.next
面试题 02.07. 链表相交
开始想法是每个往后移动一个,依次往后遍历,最多为2n,但是确实不能实现所有的情况
题解很牛,学到了😭
# 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:
pointerA = headA
pointerB = headB
while pointerA != pointerB:
pointerA = pointerA.next if pointerA else headB
pointerB = pointerB.next if pointerB else headA
return pointerA
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]:
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
break
if fast and fast.next: pass
else: return None
while head != fast:
head = head.next
fast = fast.next
return fast
- 虚拟头节点可以防止在链表头和链表尾部的不同规则,使得一个规则可以完成对头和中间的操作
- 注意and的逻辑
- 非常重要的是虚拟头节点和快慢指针,基本问题都可以解决
24. 两两交换链表中的节点
感觉写的时候有点迷迷糊糊的,但是结果竟然对了
# 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]:
# 尝试使用创设的虚拟节点来进行互换
node0 = dummy = ListNode(next = head)
node1 = head
while node1 and node1.next:
node2 = node1.next
node0.next = node1.next
node1.next = node2.next
node2.next = node1
node0 = node1
node1 = node1.next
return dummy.next
注意and的逻辑:
- 在 Python 中,如果
node1
是尾节点(即node1
为None
),node1 and node1.next
不会报错。这是因为 Python 中的 and 运算符是短路运算符,它会在第一个条件为假时立即停止并返回假。 - 因此,如果
node1
是尾节点,条件node1 and node1.next
中的第一个条件node1
会被解释为假(False),然后 Python 将停止计算并返回假,而不会进一步检查node1.next
是否存在,也就不会报错。
19.删除链表的倒数第N个节点
利用了虚拟头节点进行运用,但是结果上还是要分类讨论是否重新定义了head
# 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]:
p = head
p_dele_before = ListNode(next = head)
i = 1
while p.next != None:
if i >= n:
p_dele_before = p_dele_before.next
p = p.next
i += 1
if i > n and i != 1:
p_dele_before.next = p_dele_before.next.next
return head
elif i == n and i != 1:
p_dele_before.next = p_dele_before.next.next
return p_dele_before.next
else:
return 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 removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
left = right = dummy = ListNode(next = head)
for _ in range(n):
right = right.next
while right.next:
left = left.next
right = right.next
left.next = left.next.next
return dummy.next
面试题 02.07. 链表相交
开始想法是每个往后移动一个,依次往后遍历,最多为2n,但是确实不能实现所有的情况
题解很牛,学到了😭
# 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:
pointerA = headA
pointerB = headB
while pointerA != pointerB:
pointerA = pointerA.next if pointerA else headB
pointerB = pointerB.next if pointerB else headA
return pointerA
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]:
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
break
if fast and fast.next: pass
else: return None
while head != fast:
head = head.next
fast = fast.next
return fast