文章目录
1. 删除节点/基础概念类题目
1.1 删除中间节点
实现一种算法,删除单向链表中间的某个节点(即不是第一个或最后一个节点),假定你只能访问该节点。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
if node != None:
if node.next!=None:
node.val=node.next.val
node.next=node.next.next
else:
node=None
1.2 删除链表的节点【1个】
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
题目保证链表中节点的值互不相同,返回删除后的链表的头节点。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, head: ListNode, val: int) -> ListNode:
if head==None:
return(head)
else:
if head.val==val:
return(head.next)
else:
current=head
while current.next!=None:
if current.next.val==val:
current.next=current.next.next
break
current=current.next
return(head)
1.3 移除链表元素【多个】
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeElements(self, head: ListNode, val: int) -> ListNode:
if head==None:
return(None)
if head.val==val:
return(self.removeElements(head.next,val))
else:
head.next=self.removeElements(head.next,val)
return(head)
1.4 保留m个删除n个
给定链表 head 和两个整数 m 和 n;保留前m个节点,删除接下来的n个节点;一直进行这个操作,直到遍历整个链表。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def deleteNodes(self, head: ListNode, m: int, n: int) -> ListNode:
if head==None:
return(None)
a=b=head
i=0
while i<m-1 and a.next!=None and b.next!=None:
a=a.next
b=b.next
i=i+1
i=0
while i<n and b.next!=None:
b=b.next
i=i+1
a.next=self.deleteNodes(b.next,m,n)
return(head)
2. 链表重排
2.1 反转链表
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if head==None or head.next==None:
return(head)
new=self.reverseList(head.next)
current=new
while current.next!=None:
current=current.next
current.next=ListNode(head.val)
return(new)
2.2 重排链表
(1)非指针方法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reorderList(self, head: ListNode) -> None:
"""
Do not return anything, modify head in-place instead.
"""
if head==None or head.next==None or head.next.next==None:
return(head)
current=head
list_head=[]
list_head.append(head.val)
while current.next!=None:
current=current.next
list_head.append(current.val)
left=0
right=len(list_head)-1
current=head
while left<=right:
if left!=right:
current.val=list_head[left]
current.next.val=list_head[right]
current=current.next.next
left=left+1
right=right-1
else:
current.val=list_head[left]
break
return(head)
(2) 指针方法【这个答案超时了】
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reorderList(self, head: ListNode) -> None:
"""
Do not return anything, modify head in-place instead.
"""
if head==None or head.next==None or head.next.next==None:
return(head)
first=head
second=head.next
while second.next!=None:
second=second.next
first=first.next
first.next=None
second.next=self.reorderList(head.next)
head.next=second
return(head)
3. 双指针方法
3.1 链表倒数第 k 个节点
实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def kthToLast(self, head: ListNode, k: int) -> int:
if head==None:return(None)
first_i=head
second_i=head
i=1
while i<k and second_i.next!=None:
second_i=second_i.next
i=i+1
while second_i.next!=None:
first_i=first_i.next
second_i=second_i.next
return(first_i.val)
3.2 链表的中间节点
给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
if head==None or head.next==None:
return(head)
slow=head
fast=head
while fast.next!=None:
slow=slow.next
if fast.next==None or fast.next.next==None:
return(slow)
else:
fast=fast.next.next
return(slow)
3.2 给单链表加一
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def plusOne(self, head: ListNode) -> ListNode:
def f_examine(head):
if head==None or head.next==None:
return(head)
start_i=head
end_i=head.next
while end_i!=None:
if end_i.val>=10:
start_i.val=start_i.val+end_i.val//10
end_i.val=end_i.val%10
if start_i.val<10:
return(head)
else:
return(f_examine(head))
else:
start_i=start_i.next
end_i=end_i.next
return(head)
head=ListNode(0,head)
start_i=head
end_i=head.next
while end_i.next!=None:
start_i=start_i.next
end_i=end_i.next
end_i.val=end_i.val+1
res=f_examine(head)
return(res if res.val!=0 else res.next)
4.链表结构类
4.1 是否有环 & 环的起点
(1)环路检测1
(2)环路检测2
这俩题目可以用同一个方法,只是如果有环的话,返回node还是返回True;如果[环路检测1]需要O(1)空间的话,用快慢指针即可。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
if head==None:
return(None)
visited={}
current=head
while current.next!=None:
if current in visited:
return(current)
else:
visited[current]=1
current=current.next
return(None)