前言
笔者在上一篇文章中已经写好了链表的前面一半内容,剩下的部分将在本文中呈现。
一、删除链表的倒数第N个节点
LeetCode第19题:
链表的题目相对来说都比较简单,这题同样如此,最为直观的解法为首先通过while循环遍历整个链表找到节点个数size,然后找到倒数第n个节点的正序m,最后再通过一个while循环找到指定节点并删除。代码如下:
# 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]:
size = 0
dummy_head = ListNode()
demo = ListNode()
res = ListNode()
res = dummy_head
demo.next = dummy_head
dummy_head.next = head
while dummy_head.next:
size += 1
dummy_head = dummy_head.next
m = size - n + 1 #正数第m个
# if n == size:
# return head.next
for i in range(m):
demo = demo.next
demo.next = demo.next.next
return res.next
看到结果发现,该方法好像还行,所以没有尝试其他方法结题,但是感觉递归好像能简化问题。以后再尝试。
二、链表相交
LeetCode第2818题(面试题):
这一题是简单题,直接想到的思想是先将两个链表"对齐",然后遍历后续节点,找到相交点。而具体的操作是先分别遍历两个链表计算长度,如果链表A长于链表B则将二者交换,确保B的长度大于A,在遍历链表B(较长的那个),使得其剩余长度与A保持一致,最后同时遍历剩下的元素,找到相交点。
需要注意的有两点:
(1)相交不是val相等而是cur相等
(2)Python交换a、b有如下简单写法:a, b = b, a
代码如下:
# 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:
size1 = 0
size2 = 0
head1 = headA
head2 = headB # 避免head位置出现调动
skipA = 0
skipB = 0
while head1:
size1 += 1
head1 = head1.next
while head2:
size2 += 1
head2 = head2.next
head1 = headA
head2 = headB
if size1 > size2: # 8-6 index = size1 - size2:
head1, head2 = head2, head1
size1, size2 = size2, size1
# 如果1 > 2,交换二者位置,使得2 > 1
index = size2 - size1
for i in range(index):
head2 = head2.next
# 将A、B对齐
while head1:
# if head1.val == head2.val:
if head1 == head2:
return head1
else:
head1 = head1.next
head2 = head2.next
return None
采用这种方法结题的时间复杂度为O(m + n),空间复杂度为O(1),但是并没有找到O(n)的结题方法。
三、环形链表Ⅱ
LeetCode第142题:
主要把握两点:
(1)如果有环,fast一定能追上slow
(2)fast比slow多走n倍环距离,所以环剩下的距离一定与入口距离呈现c = a + n(a + b)
代码如下:
# 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
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
fast = head
while fast != slow:
fast = fast.next
slow = slow.next
return fast
return None
总结
链表的题目到此结束,下一阶段将继续学习哈希表。