链接:LeetCode
[Leetcode]5356. 矩阵中的幸运数
给一个(m * n)的矩阵,矩阵中的数字 各不相同 。请按任意顺序返回矩阵中的所有幸运数。
幸运数是指矩阵中满足同时下列两个条件的元素:
- 在同一行的所有元素中最小
- 在同一列的所有元素中最大
示例 1:
输入:matrix = [[3,7,8],[9,11,13],[15,16,17]]
输出:[15]
解释:15 是唯一的幸运数,因为它是其所在行中的最小值,也是所在列中的最大值。
这题暴力解即可,循环判断矩阵行(列)的最小(大)值。
class Solution:
def luckyNumbers (self, matrix: List[List[int]]) -> List[int]:
n,m = len(matrix),len(matrix[0])
res1 = set()
res2 = set()
for i in range(n):
min_num = min(matrix[i])
res1.add(min_num)
for j in range(m):
nums = [x[j] for x in matrix]
max_num = max(nums)
res2.add(max_num)
res = list(res1 & res2)
return res
[Leetcode]1381. 设计一个支持增量操作的栈
请你设计一个支持下述操作的栈。
- 实现自定义栈类 CustomStack :
- CustomStack(int maxSize):用 maxSize 初始化对象,maxSize 是栈中最多能容纳的元素数量,栈在增长到 maxSize 之后则不支持 push 操作。
- void push(int x):如果栈还未增长到 maxSize ,就将 x 添加到栈顶。
- int pop():返回栈顶的值,或栈为空时返回 -1 。
- void inc(int k, int val):栈底的 k 个元素的值都增加 val 。如果栈中元素总数小于 k ,则栈中的所有元素都增加 val 。
示例:
输入:
(["CustomStack","push","push","pop","push","push","push","increment","increment","pop","pop","pop","pop"])
([[3],[1],[2],[],[2],[3],[4],[5,100],[2,100],[],[],[],[]])
输出:
([null,null,null,2,null,null,null,null,null,103,202,201,-1])
解释:
CustomStack customStack = new CustomStack(3); // 栈是空的 []
customStack.push(1); // 栈变为 [1]
customStack.push(2); // 栈变为 [1, 2]
customStack.pop(); // 返回 2 --> 返回栈顶值 2,栈变为 [1]
customStack.push(2); // 栈变为 [1, 2]
customStack.push(3); // 栈变为 [1, 2, 3]
customStack.push(4); // 栈仍然是 [1, 2, 3],不能添加其他元素使栈大小变为 4
customStack.increment(5, 100); // 栈变为 [101, 102, 103]
customStack.increment(2, 100); // 栈变为 [201, 202, 103]
customStack.pop(); // 返回 103 --> 返回栈顶值 103,栈变为 [201, 202]
customStack.pop(); // 返回 202 --> 返回栈顶值 202,栈变为 [201]
customStack.pop(); // 返回 201 --> 返回栈顶值 201,栈变为 []
customStack.pop(); // 返回 -1 --> 栈为空,返回 -1
搞清规则后,朴素的思想是建立一个stack,每次increment的时候遍历栈进行累加即可。一种更好的方法,其实是不用对前k个数都进行累加的,只需要对k-1个数进行记录,在pop的时候进行累加的同时,将累加值也记录到前一个元素中。这样能大大减少累加的时间复杂度。
最后,要注意k可能大于stack的大小,需要对k进行判断。
class CustomStack:
def __init__(self, maxSize: int):
self.stack = []
self.maxSize = maxSize
self.size = 0
def push(self, x: int) -> None:
if self.size ==self.maxSize:
return
else:
self.stack.append([x,0])
self.size += 1
def pop(self) -> int:
if not self.size:return -1
val,inc = self.stack.pop()
self.size -= 1
if self.size:
self.stack[-1][1] += inc
return val+inc
def increment(self, k: int, val: int) -> None:
k = min(k,self.size)
# 防止k为0
if k:
self.stack[k-1][1] += val
# Your CustomStack object will be instantiated and called as such:
# obj = CustomStack(maxSize)
# obj.push(x)
# param_2 = obj.pop()
# obj.increment(k,val)```
[Leetcode]1382. 将二叉搜索树变平衡
给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。
如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平衡的 。如果有多种构造方法,请你返回任意一种。
通过中序遍历获取数组,然后重建平衡二叉搜索树即可。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def balanceBST(self, root: TreeNode) -> TreeNode:
nums = []
self.dfs(root,nums)
return self.reBuildBST(nums)
def dfs(self,root,nums):
if not root:
return
self.dfs(root.left,nums)
nums.append(root.val)
self.dfs(root.right,nums)
def reBuildBST(self,nums):
if not nums:return
mid = len(nums)//2
root = TreeNode(nums[mid])
root.left,root.right = self.reBuildBST(nums[:mid]),self.reBuildBST(nums[mid+1:])
return root
[Leetcode]1383. 最大的团队表现值
公司有编号为 1 到 n 的 n 个工程师,给你两个数组 speed 和 efficiency ,其中(speed[i])和(efficiency[i])分别代表第 i 位工程师的速度和效率。请你返回由最多 k 个工程师组成的 最大团队表现值 ,由于答案可能很大,请你返回结果对(10^9 + 7)取余后的结果。
团队表现值 的定义为:一个团队中「所有工程师速度的和」乘以他们「效率值中的最小值」。
示例 1:
输入:(n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 2)
输出:60
解释:
我们选择工程师 2(speed=10 且 efficiency=4)和工程师 5(speed=5 且 efficiency=7)。他们的团队表现值为 performance = (10 + 5) * min(4, 7) = 60 。
示例 2:
输入:(n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 3)
输出:68
解释:
此示例与第一个示例相同,除了 k = 3 。我们可以选择工程师 1 ,工程师 2 和工程师 5 得到最大的团队表现值。表现值为 performance = (2 + 10 + 5) * min(5, 4, 7) = 68 。
示例 3:
输入:(n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 4)
输出:72
一个trick是要求某个值乘以某个最大(小)值的时候可以通过分解局部最优优化时间复杂度。 难点在于怎么对数组进行遍历解局部最优解。这里,我们可以将局部解认为是:求必须取当前元素且当前元素为最小值的情况下,最优解是什么。最后求局部解的最大值,即是全局最优解。
所以核心思路是:先以效率对所有工程师做降序排序,每次选定一个效率值作为(x),从效率值大于 (x)的工程师(即左侧的工程师)中找到速度最大的至多(K-1)个工程师,从而计算他们的团队表现值。
为了方便的找到效率大于(x)的速度最大的(K-1)个工程师,使用一个容量为(K-1)的小顶堆来维护。
import heapq
class Solution:
def maxPerformance(self, n: int, speed: List[int], efficiency: List[int], k: int) -> int:
nums = list(zip(speed,efficiency))
nums.sort(key = lambda x:-x[1])
res = sum_ = 0
min_heap = []
for i in range(len(nums)):
eff,spp = nums[i]
res = max(res,(eff+sum_)*spp)
if i<k-1:
heapq.heappush(min_heap,eff)
sum_ += eff
elif min_heap and eff > min_heap[0]:
num = heapq.heapreplace(min_heap,eff)
sum_ += eff-num
return res%(10**9+7)