https://leetcode-cn.com/conte...
第一题 5340.统计有序矩阵中的负数
https://leetcode-cn.com/conte...
class Solution:
def countNegatives(self, grid: List[List[int]]) -> int:
n = len(grid)
m = len(grid[0])
c = 0
for i in range(n-1, -1, -1):
if grid[i][-1] >= 0: break
for j in range(m-1, -1, -1):
if grid[i][j] < 0:
c += 1
else:
break
return c
第二题 5341.最后 K 个数的乘积
https://leetcode-cn.com/conte...
第一可能查询的次数很多,区间也可能很大,如果每次查询都现算可能超时。但是每个数字都不大。
这时候就考虑不存数字本身,而是存连乘后的结果。例如输入的 a b c d。则存的是 a,a×b,a×b×c,a×b×c×d。这样。如果查询最后两个数相乘,就是倒数第一除以倒数第三就是 (a×b×c×d)/ (a×b)= c × d。这样每次查询只需要做一次除法,每次输入只需要做一次乘法。
用 python 的一个优势是,不用考虑整数溢出的问题。
这里还有一个问题没有处理,就是 0。当时没考虑到,但是样例救了我,跑样例除了除零错误。
对于 0 的思路是,每次遇到 0 直接清空列表,因为前面是啥都没用了,只要超过 0 的位置,前面的都是 0 了。
而相应的查询的地方,长度超过列表长度,直接返回 0,因为面前肯定是遇到 0 了。
再一个为了代码方便,直接列表第一个默认自带一个 1。
class ProductOfNumbers:
def __init__(self):
self.p = [1]
def add(self, num: int) -> None:
if num == 0:
self.p = [1]
else:
self.p.append(self.p[-1] * num)
def getProduct(self, k: int) -> int:
if k >= len(self.p): return 0
return self.p[-1] // self.p[-k-1]
# Your ProductOfNumbers object will be instantiated and called as such:
# obj = ProductOfNumbers()
# obj.add(num)
# param_2 = obj.getProduct(k)
第三题 5342.最多可以参加的会议数目
https://leetcode-cn.com/conte...
贪心算法。使用优先队列,先从最小的一天开始安排。
策略是按照开始日期分组,每一组(也就是每天)只取一个结束时间最早的(也就是会议长度最短的)。然后这把一组其他的所有其他会议的开始时间修改为下一天,放入优先队列排序。
大致是在这样,但是可以有一些小的优化,比如结束日期就是当前处理的一天的会议就可以直接安排上。因为这个会议安排上一定不会影响后面别的会。
整体的贪心策略就是尽可能安排这一天开一个结束日期最早的会。
import queue
class Solution:
def maxEvents(self, events: List[List[int]]) -> int:
q = queue.PriorityQueue()
for e in events:
q.put(e)
e = q.get()
cnt = 1
cd = e[0] + 1
while not q.empty():
e = q.get()
if e[0] == cd:
if e[1] >= cd:
cd += 1
cnt += 1
elif e[0] > cd:
cd = e[0] + 1
cnt += 1
else: # e[0] < cd
if e[1] == cd:
cd += 1
cnt += 1
if e[1] > cd:
e[0] = cd
q.put(e)
return cnt
第四题 5343.多次求和构造目标数组
https://leetcode-cn.com/conte...
看起来很难,但是找到规律后实现很简单。
因为两个步骤是交替进行的。所以:
- 当前数组中最大的一个数必然是当前的 x(代码中的 current_x)。
- 数组所有数的和减去这个最大数,就是这次的 x 比上一次 x 增大的增量(inc)。
经过 wangtaoking1 提醒,修改了循环中更新 x 的方法。之前是 x = x - val,现在是 x = x % val。我比赛的代码可能超时,只是测试数据比较弱才侥幸过了。
后来又经过 zdyxry ,@Gorilla 提醒又做了两次修改。 增加对 current_x % inc
为 0 的判断。
class Solution:
def isPossible(self, target: List[int]) -> bool:
if len(target) == 1: return target[0] == 1
while True:
current_x = max(target)
if current_x == 1:
return True # 最大的数等于 1 了而且数组中无小于 1 的数,那么说明整个数组都是 1,返回 True
idx = target.index(current_x)
inc = sum(target) - current_x
target[idx] = current_x % inc
if inc >= current_x or target[idx] == 0:
return False # inc 大于等于 x,这样将会出现小于 1 的值,不是合法情况,返回 False
欢迎来我的博客: https://codeplot.top/
我的博客刷题分类:https://codeplot.top/categories/%E5%88%B7%E9%A2%98/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。