力扣周赛333
2056. 二进制矩阵中的特殊位置
题目描述
给你一个 m x n
的二进制矩阵 mat
。如果一个单元格中有且仅有一个 1
,我们称它为 特殊位置。
请你返回矩阵中 特殊位置 的数目。
题解思路
一种简单的方法是遍历矩阵中的每个元素,如果它是 1
,就检查它所在的行和列是否都只有一个 1
。如果是,就说明它是一个特殊位置,否则不是。这样做的时间复杂度是 O(mn * (m + n))
,空间复杂度是 O(1)
。
另一种优化的方法是预处理矩阵,用两个数组分别记录每行和每列的 1
的个数。这样就可以在 O(1)
的时间内判断一个元素是否是特殊位置。这样做的时间复杂度是 O(mn)
,空间复杂度是 O(m + n)
。
代码实现
class Solution:
def numSpecial(self, mat: List[List[int]]) -> int:
# 预处理每行和每列的1的个数
m, n = len(mat), len(mat[0])
row = [0] * m # row[i]表示第i行的1的个数
col = [0] * n # col[j]表示第j列的1的个数
for i in range(m):
for j in range(n):
if mat[i][j] == 1:
row[i] += 1
col[j] += 1
# 遍历矩阵,统计特殊位置的数目
ans = 0
for i in range(m):
for j in range(n):
if mat[i][j] == 1 and row[i] == 1 and col[j] == 1:
ans += 1
return ans
2057. 最小化目标值与所选元素的差
题目描述
给你三个长度相同的整数数组 nums1
、nums2
和 nums3
,请你从每个数组中选出一个元素,组成一个大小为 3
的数组。
设选出的元素分别为 a
、b
和 c
,请你返回一个 最小化 的结果:|a - b| + |b - c| + |c - a|
。
题解思路
一种直观的方法是枚举所有可能的组合,计算每个组合的结果,并取最小值。这样做的时间复杂度是 O(n^3)
,空间复杂度是 O(1)
。
另一种优化的方法是先对三个数组进行排序,然后使用三个指针分别指向三个数组的当前元素。每次计算当前指针所指元素的结果,并更新最小值。然后移动指向最小元素的指针,直到有一个数组遍历完毕。这样做的时间复杂度是 O(nlogn)
,空间复杂度是 O(1)
。
代码实现
class Solution:
def minAbsDifference(self, nums1: List[int], nums2: List[int], nums3: List[int]) -> int:
# 对三个数组进行排序
nums1.sort()
nums2.sort()
nums3.sort()
# 使用三个指针分别指向三个数组的当前元素
i, j, k = 0, 0, 0
n = len(nums1)
# 初始化最小值为无穷大
ans = float('inf')
# 遍历三个数组,直到有一个数组遍历完毕
while i < n and j < n and k < n:
# 计算当前指针所指元素的结果
a, b, c = nums1[i], nums2[j], nums3[k]
res = abs(a - b) + abs(b - c) + abs(c - a)
# 更新最小值
ans = min(ans, res)
# 移动指向最小元素的指针
if a <= b and a <= c:
i += 1
elif b <= a and b <= c:
j += 1
else:
k += 1
return ans
2058. 找出最具竞争力的子序列
题目描述
给你一个整数数组 nums
和一个正整数 k
,返回长度为 k
且最具 竞争力 的 nums
子序列。
数组的子序列是从数组中删除一些元素(可能不删除元素)得到的序列。
在子序列 a
和子序列 b
第一个不相同的位置上,如果 a
中的数字小于 b
中对应的数字,那么我们称子序列 a
比子序列 b
(相同长度下)更具 竞争力。例如,[1,3,4]
比 [1,3,5]
更具竞争力,在第一个不相同的位置,也就是最后一个位置上, 4
小于 5
。
题解思路
一种直观的方法是枚举所有长度为 k
的子序列,比较它们的竞争力,并取最小的一个。这样做的时间复杂度是 O(n^k)
,空间复杂度是 O(k)
。
另一种优化的方法是使用单调栈。单调栈是一种数据结构,它可以维护一个单调递增或递减的序列。我们可以从左到右遍历数组,每次遇到一个元素,就尝试将它加入单调栈中。如果加入后导致栈中元素个数超过 k
,或者破坏了单调递减的性质,就弹出栈顶元素,直到满足条件为止。这样做可以保证栈中的元素是最具竞争力的子序列。这样做的时间复杂度是 O(n)
,空间复杂度是 O(k)
。
代码实现
class Solution:
def mostCompetitive(self, nums: List[int], k: int) -> List[int]:
# 使用单调栈
stack = []
n = len(nums)
# 遍历数组
for i in range(n):
# 尝试将当前元素加入栈中
num = nums[i]
# 如果加入后导致栈中元素个数超过k,或者破坏了单调递减的性质,就弹出栈顶元素
while stack and stack[-1] > num and len(stack) + n - i > k:
stack.pop()
# 如果栈中元素个数小于k,就加入当前元素
if len(stack) < k:
stack.append(num)
# 返回栈中的元素作为结果
return stack