本周周赛还是比较简单。
5328.方阵中战斗力最弱的 K 行
水题,数组排序,
https://leetcode-cn.com/conte...
需要返回 1 最少的前 k 行,1 一样多的先返回下标小的。
- 统计每行有几个 1。
- 排序
- 返回前 k 个下标
class Solution:
def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
n = len(mat)
m = len(mat[0])
x = [[sum(l)*(n+1)+(i),i] for i,l in enumerate(mat)]
x.sort(key=lambda x:x[0])
return [x[i][1] for i in range(k)]
5329.数组大小减半
水题
https://leetcode-cn.com/conte...
- 先求数组长度。
- 再求数组中每个元素出现的次数。
- 对次数排序
- 从大到小遍历,依次累加,直到超过长度的一半
- 返回累加了几个数
import collections
class Solution:
def minSetSize(self, arr: List[int]) -> int:
cnt = collections.Counter(arr)
l = len(arr)
x = list(cnt.values())
x.sort(reverse=True)
ans = 0
c = 0
while c < l / 2:
c += x[ans]
ans += 1
return ans
5330.分裂二叉树的最大乘积
https://leetcode-cn.com/conte...
本质上是把一组整数分成两组,让两组的和的乘积最大。分裂二叉树就是从树上拿出一个子树来。
尽量让两组和接近可以得到最大乘积。
先求所有节点的和。
然后再遍历整棵树,看哪个子树的和与所有节点和的一半最接近。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def maxProduct(self, root: TreeNode) -> int:
self.sum = 0
self.cur_t = 0
def get_sum(r):
if r:
self.sum += r.val
if not r.left and not r.right:
self.cur_t = r.val
else:
get_sum(r.left)
get_sum(r.right)
get_sum(root)
self.target = self.sum/2
self.cur_x = abs(self.target-self.cur_t)
# print(self.sum, self.target, self.cur_t, self.cur_x)
def find_tar(r):
if r:
s = r.val
s += find_tar(r.left)
s += find_tar(r.right)
cur_x = abs(s - self.target)
if cur_x < self.cur_x:
self.cur_t = s
self.cur_x = cur_x
return s
else:
return 0
find_tar(root)
return ((self.sum - self.cur_t) * self.cur_t) % 1000000007
5331.跳跃游戏 V
有向图上求最长路径。
把这个数组转换成一个无环有向图。
利用 mp 数组存每个点能直接到达的节点。
dfs 用于递归求一个点的解。一个点的解就是这个点能到的所有点里解最大的一个加一。(如果他哪也到不了,就是 1)
ansx 做了记忆化搜索,防止求重复的点的解。这里可以使用 functools 中的 lru_cache(None) 代替自己定义数组,写法更简洁。
class Solution:
def maxJumps(self, arr: List[int], d: int) -> int:
l = len(arr)
mp = [[] for i in range(l)]
for i in range(l):
j = i - 1
while j >= 0:
if i - j > d: break
if arr[j] >= arr[i]: break
mp[i].append(j)
j -= 1
j = i + 1
while j < l:
if j - i > d: break
if arr[j] >= arr[i]: break
mp[i].append(j)
j += 1
ansx = [0] * l
def dfs(i):
if ansx[i] != 0: return ansx[i]
if len(mp[i]) == 0:
ansx[i] = 1
return 1
ans = dfs(mp[i][0])
for toid in mp[i][1:]:
ans = max(ans, dfs(toid))
ansx[i] = ans + 1
return ans + 1
ans = dfs(0)
for i in range(1, l):
ans = max(ans, dfs(i))
return ans
使用 functools.lru_cache 的代码:
import functools
class Solution:
def maxJumps(self, arr: List[int], d: int) -> int:
l = len(arr)
mp = [[] for i in range(l)]
for i in range(l):
j = i - 1
while j >= 0:
if i - j > d: break
if arr[j] >= arr[i]: break
mp[i].append(j)
j -= 1
j = i + 1
while j < l:
if j - i > d: break
if arr[j] >= arr[i]: break
mp[i].append(j)
j += 1
@functools.lru_cache(None)
def dfs(i):
if len(mp[i]) == 0:
return 1
ans = dfs(mp[i][0])
for toid in mp[i][1:]:
ans = max(ans, dfs(toid))
return ans + 1
ans = dfs(0)
for i in range(1, l):
ans = max(ans, dfs(i))
return ans
我的博客:https://codeplot.top/
我的刷题:https://codeplot.top/categories/刷题/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。