2089.找出数组排序后的目标下标
方法一:排序+遍历
class Solution(object):
def targetIndices(self, nums, target):
ans = []
nums.sort()
for i, w in enumerate(nums):
if w == target:
ans.append(i)
return ans
for i, w in enumerate(nums):
# i 表示数组下标
# w 表示数组下标对应的值
# enumerate 枚举
时间复杂度: O ( n log n ) O(n\log n) O(nlogn)
空间复杂度: O ( log n ) O(\log n) O(logn),排序的栈空间开销
方法二:一次遍历
class Solution(object):
def targetIndices(self, nums, target):
count1 = 0
count2 = 0
ans = []
for num in nums:
if num < target:
count1 += 1
elif num == target:
count2 += 1
for i in range(count1, count1 + count2):
ans.append(i)
return ans
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
2090.半径为k的子数组平均值
滥用除法会导致结果相差一。因此遇到需要整除或向下取整这些东西,尽量只使用一次,即在获取最终结果时
W
n
e
w
=
W
o
l
d
−
L
e
f
t
+
R
i
g
h
t
a
n
s
=
[
W
n
e
w
2
×
k
+
1
]
W_{new} = W_{old} - Left + Right \\ ans = [\frac{W_{new}}{2\times k + 1}]
Wnew=Wold−Left+Rightans=[2×k+1Wnew]
class Solution(object):
def getAverages(self, nums, k):
n = len(nums)
ans = [-1] * n # 全部设为-1,省去两个循环
# 如果k满足条件
if 2 * k + 1 <= n:
temp = sum(nums[:2 * k])
for i in range(k, n - k):
temp += nums[i + k]
ans[i] = temp // (2 * k + 1)
temp -= nums[i - k]
return ans
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
2091.从数组中移除最大值和最小值
贪心算法
- 都在前面一起删除,删除一次
- 都在后面一起删除,删除一次
- 一个在前面,一个在后面,分开删除,步骤加起来
数学语言表示
假设数组长度为 n n n, 最小值在 i i i, 最大值在 j j j, 并且 i < = j i<=j i<=j, 则按上面的三种情况分别删除
- j + 1 j+1 j+1
- n − i n-i n−i
- i + 1 + n − j i + 1 + n - j i+1+n−j
取出三者最小值
class Solution(object):
def minimumDeletions(self, nums):
Max, maxIndex = float("-inf"), 0
Min, minIndex = float("inf"), 0
n = len(nums)
for i in range(n):
# 题目已经要求nums中的正数互不相同
if nums[i] > Max:
Max, maxIndex = nums[i], i
if nums[i] < Min:
Min, minIndex = nums[i], i
if maxIndex < minIndex:
maxIndex, minIndex = minIndex, maxIndex
return min(maxIndex + 1, n - minIndex, minIndex + 1 + n - maxIndex)
# 取出极值的索引
minIndex = nums.index(min(nums))
maxIndex = nums.index(max(nums))
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
2092.找出知晓秘密的所有专家
- 根据时间排序
- 不同时间段建立无向图
- 广度优先搜索
class Solution(object):
def findAllPeople(self, n, meetings, firstPerson):
isVisited = [0] * n
# 专家0和firstPerson知道秘密
isVisited[0], isVisited[firstPerson] = 1, 1
# 按时间排列会议
meetings.sort(key = lambda x : x[2])
i, j = 0, 0
while j < len(meetings):
while j < len(meetings) and meetings[i][2] == meetings[j][2]:
j += 1
# 对每个时间段建无向图
vertexs, edges = set(), defaultdict(list)
for meeting in meetings[i : j]:
vertexs.add(meeting[0])
vertexs.add(meeting[1])
edges[meeting[0]].append(meeting[1])
edges[meeting[1]].append(meeting[0])
# 先把已经知道秘密的成员提取出来
q = deque([])
for vertex in vertexs:
if isVisited[vertex]:
q.append(vertex)
# BFS
while q:
p = q.popleft()
for v in edges[p]:
if isVisited[v] == 0:
isVisited[v] = 1
q.append(v)
i = j
ans = []
for i in range(n):
if isVisited[i] == 1:
ans.append(i)
return ans
时间复杂度: O ( m log m + n ) O(m\log m+n) O(mlogm+n),排序需要 O ( m log m ) O(m\log m) O(mlogm),广度优先搜索只需要 O ( n ) O(n) O(n)。
空间复杂度: O ( m + n ) O(m+n) O(m+n),广度优先搜索需要的空间。