[Leetcode Weekly Contest]180

链接: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)

猜你喜欢

转载自www.cnblogs.com/hellojamest/p/12503073.html
今日推荐