[Leetcode Weekly Contest]176

链接:LeetCode

[Leetcode]5340. 统计有序矩阵中的负数

给一个mn的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。 
请你统计并返回 grid 中 负数 的数目。
示例 1:

输入:grid = [[4,3,2,1],[3,2,1,1],[1,1,1,2],[1,1,2,3]]
输出:8
解释:矩阵中共有 8 个负数。

因为是非递增顺序排列,所以最小的数在矩阵左下角,每次跟矩阵左下角进行比较即可,时间复杂度O(m+n)

class Solution:
    def countNegatives(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        r, c, cnt = m - 1, 0, 0
        while r >= 0 and c < n:
            if grid[r][c] < 0:
                cnt += n - c
                r -= 1
            else:
                c += 1
        return cnt

[Leetcode]5341. 最后 K 个数的乘积

实现一个「数字乘积类」ProductOfNumbers,要求支持下述两种方法:
1. add(int num)

将数字 num 添加到当前数字列表的最后面。
2. getProduct(int k)

返回当前数字列表中,最后k个数字的乘积。
你可以假设当前列表中始终 至少 包含k个数字。
题目数据保证:任何时候,任一连续数字序列的乘积都在 32-bit 整数范围内,不会溢出。

类似于在数组中寻找K个数的和,我们可以先求出从开始位到每一位的总积,然后用总积除以从开始位到最后k-1位的总积,即可。但有一种特殊情况就是出现了0,当出现0的时候,后面每一个位置的总积都是0,无法用这种方法,这个时候我们将数组清零即可,当判断最后k个数字的乘积,如果数组个数小于K个,则说明之前是出现了0。这也是最简单的一种判别方法了。

class ProductOfNumbers:

    def __init__(self):
        self.products = []

    def add(self, num: int) -> None:
        if not num:
            self.products = []
        else:
            if not self.products:
                self.products.append(num)
            else:
                self.products.append(self.products[-1]*num)
        
    def getProduct(self, k: int) -> int:
        if k>len(self.products):
            return 0
        if k == len(self.products):
            return self.products[-1]
        n = len(self.products)
        return self.products[-1]//self.products[n-k-1]

[Leetcode]5342. 最多可以参加的会议数目

给你一个数组 events,其中events[i]=[startDayi,endDayi],表示会议i开始于 startDayi,结束于endDayi
你可以在满足startDayi<=d<=endDayi中的任意一天d参加会议i。注意,一天只能参加一个会议。
请你返回你可以参加的最大会议数目。

输入:events = [[1,2],[2,3],[3,4]]
输出:3
解释:你可以参加所有的三个会议。
安排会议的一种方案如上图。
第 1 天参加第一个会议。
第 2 天参加第二个会议。
第 3 天参加第三个会议。

这实际是一道考验贪婪法求解的题目。首先,我们很明确一个事情,就是给定一个event,如果我要参加其会议,当然是越早越好,这可以给后面的会议让出时间,所以选择不是问题,而问题在于排序。怎么明确,先参加哪个会议呢?
答案是endDayi最小的那个。假设我们先将endDayi排序,那么对于endDayi最小的那个会议,我选择其startDayi一天参加会议不会影响后面的会议的选择。想想反证法:假设我们占用了任何一个其他会议eventj的时间,最佳的选择应该是会议eventjstartDayi,而会议eventi在其他时间,那么这种情况对于eventiendDayi<=endDayj,所以无论会议
eventi选在哪个时间,eventj也可以选择那个时间。这说明,我们选任何一个其他会议eventj的情况,都能在先选eventi的策略中找到一样的,即选择endDayi最小的那个会议先参加,其最大会议数目大于等于先参加其他任何会议。
接下来,我们用一个集合set来存储我们参加会议的时间即可。

class Solution:
    def maxEvents(self, events: List[List[int]]) -> int:
        if not events or not events[0]:
            return 0
        events = sorted(events, key=lambda x: x[1])
        visited = set()
        for s, e in events:
            for t in range(s, e+1):
                if t not in visited:
                    visited.add(t)
                    break
        return len(visited)

[Leetcode]5343. 多次求和构造目标数组

给你一个整数数组 target 。一开始,你有一个数组 A ,它的所有元素均为 1 ,你可以执行以下操作:

令 x 为你数组里所有元素的和
选择满足 0 <= i < target.size 的任意下标 i ,并让 A 数组里下标为 i 处的值为 x 。
你可以重复该过程任意次
如果能从 A 开始构造出目标数组 target ,请你返回 True ,否则返回 False 。

示例 1:
输入:target=[9,3,5]
输出:true
解释:从 [1,1,1] 开始
[1,1,1], 和为 3 ,选择下标 1
[1,3,1], 和为 5, 选择下标 2
[1,3,5], 和为 9, 选择下标 0
[9,3,5] 完成

这是一道贪婪+堆的题目。
首先,我们先看看例子,对于target=[9,3,5],虽然我们不知道[1,1,1]怎么开始求和构成成如此数组,但显然最后一层构造所替换掉的元素,必然是数组中的最大值,也就是9。接下来,我们要逆向思考,9之前替换的数字是什么呢?根据规则,我们知道,9,即x等于3加5加本来的元素,所以本来的元素是1,那么此时,target=[1,3,5],接下来,我们再按照这种方式求最大值原来的值是多少,并进行替换即可。
这里比较高效的方法是大顶堆,在每次进行pop的时候,提取出数组最大值,然后把替换前的数push进去,这里有两个技巧:
1.因为是大顶堆,python默认的 heapq是小顶堆,所以我们放入的时候取负数即可。
2.如果我们计算出的替换出的数<1,那么说明这是无法从[1,1,1] 开始构造而成的,返回False即可。

class Solution:
    def isPossible(self, target: List[int]) -> bool:
        total=sum(target)
        target=[-x for x in target]
        heapq.heapify(target)
        while target:
            curMax=-heapq.heappop(target)
            if curMax==1:
                return len(target)==0 or max(target)==-1
            total-=curMax
            next_sum=curMax-total
            total+=next_sum
            if next_sum < 1:
                return False
            heapq.heappush(target,-next_sum)
posted @   Jamest  阅读(213)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示