知识点
题目
- 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
- 示例:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
# 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()
dummy_head.next=head
fast_node,slow_node=dummy_head,dummy_head
while(n+1):
fast_node=fast_node.next
n-=1
while(fast_node):
slow_node=slow_node.next
fast_node=fast_node.next
slow_node.next=slow_node.next.next
return dummy_head.next
注释:
为什么不用while(fast_node.next)是因为仅有一个结点时需要单独判断。
- 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
- 示例:
图示两个链表在节点 c1 开始相交:
解法①:
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA==None or headB==None:
return None
curA,curB=headA,headB
while(curA !=curB):
curA=curA.next if curA else headB
curB=curB.next if curB else headA
return curA
证明:
考虑两种情况,第一种情况是两个链表相交,第二种情况是两个链表不相交。
情况一:两个链表相交
链表 headA 和 headB 长度分别是 m 和 n 。假设链表 headA 的不相交部分有 a 个节点,链表 headB 的不相交部分有 b 个节点,两个链表相交的部分有 c 个节点,则有 a+c=m,b+c=n。
如果 a=b,则两个指针会同时到达两个链表相交的节点,此时返回相交的节点;
如果 a ≠b,则指针 pA 会遍历完链表 headA,指针 pB 会遍历完链表 headB,两个指针不会同时到达链表的尾节点,然后指针 pA 移到链表 headB 的头节点,指针 pB 移到链表 headA 的头节点,然后两个指针继续移动,在指针 pA 移动了 a+c+b 次、指针 pB 移动了 b+c+a 次之后,两个指针会同时到达两个链表相交的节点,该节点也是两个指针第一次同时指向的节点,此时返回相交的节点。
情况二:两个链表不相交
链表 headA 和 headB 的长度分别是 m 和 n。考虑当 m=n 和 m ≠ m 时,两个指针分别会如何移动:
如果 m=n,则两个指针会同时到达两个链表的尾节点,然后同时变成空值 null,此时返回 null;
如果 m ≠ n,则由于两个链表没有公共节点,两个指针也不会同时到达两个链表的尾节点,因此两个指针都会遍历完两个链表,在指针 pA 移动了 m+n 次、指针 pB 移动了 n+m 次之后,两个指针会同时变成空值 null,此时返回 null。
解法②
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
lenA,lenB=0,0
curAA,curBB=headA,headB
#计算链表长度
while(curAA):
lenA+=1
curAA=curAA.next
while(curBB):
lenB+=1
curBB=curBB.next
#计算链表长度差
distance=abs(lenA-lenB)
curA=headA
curB=headB
#尾部对齐链表,并比较
if lenA>lenB:
while(distance):
curA=curA.next
distance-=1
while(curA):
if curA==curB:
return curA
curA=curA.next
curB=curB.next
return curA
else:
while(distance):
curB=curB.next
distance-=1
while(curB):
if curA==curB:
return curB
curA=curA.next
curB=curB.next
return curB
- 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。 - 示例:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
# 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
while(fast and fast.next):
fast=fast.next.next
slow=slow.next
if fast==slow:
index1=fast
index2=head
while(index1!=index2):
index1=index1.next
index2=index2.next
return index1
return None
讲解:
代码随想录:环形链表