[Leetcode Weekly Contest]174
作者:互联网
链接:LeetCode
[Leetcode]5328. 方阵中战斗力最弱的 K 行
给你一个大小为 m * n 的方阵 mat,方阵由若干军人和平民组成,分别用 0 和 1 表示。
请你返回方阵中战斗力最弱的 k 行的索引,按从最弱到最强排序。
如果第 i 行的军人数量少于第 j 行,或者两行军人数量相同但 i 小于 j,那么我们认为第 i 行的战斗力比第 j 行弱。
军人 总是 排在一行中的靠前位置,也就是说 1 总是出现在 0 之前。
输入:\(mat = [[1,1,0,0,0], [1,1,1,1,0], [1,0,0,0,0], [1,1,0,0,0], [1,1,1,1,1]], k = 3\)
输出:\([2,0,3]\)
按照题意排序即可。
class Solution:
def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
res = []
n,m = len(mat),len(mat[0])
for i in range(n):
num = len([x for x in mat[i] if x==1])
res.append([i,num])
res.sort(key=lambda x:[x[1],x[0]])
return [x[0] for x in res][:k]
[Leetcode]5329. 数组大小减半
给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。
返回至少能删除数组中的一半整数的整数集合的最小大小。
统计每个数出现的次数,然后排序即可。
import collections
class Solution:
def minSetSize(self, arr: List[int]) -> int:
count = collections.Counter(arr)
num = sorted(count.values())
res = 0
all_del = 0
for n in num[::-1]:
all_del+=n
res += 1
if all_del>=len(arr)//2:
return res
[Leetcode]5330. 分裂二叉树的最大乘积
给你一棵二叉树,它的根为 root 。请你删除 1 条边,使二叉树分裂成两棵子树,且它们子树和的乘积尽可能大。由于答案可能会很大,请你将结果对 10^9 + 7 取模后再返回。
要计算子树和的乘积,不如只计算一个子树的和,然后将二叉树所有和减去该树即可得另一个字数和。如此,我们只需要计算每一个字数的和,从中选取一个能组成最大子树和乘积即可。
# 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:
res = 0
dic = {}
all_sum = self.dfs(root,dic)
for val in dic.values():
res = max(res,val*(all_sum-val))
return res%(10**9 + 7)
def dfs(self,root,dic):
if not root:
return 0
if not root.left and not root.right:
dic[root] = root.val
else:
dic[root] = root.val + self.dfs(root.left,dic) + self.dfs(root.right,dic)
return dic[root]
[Leetcode]5331. 跳跃游戏 V
给你一个整数数组 arr 和一个整数 d 。每一步你可以从下标 i 跳到:
- i + x ,其中 i + x < arr.length 且 0 < x <= d 。
- i - x ,其中 i - x >= 0 且 0 < x <= d 。
除此以外,你从下标 i 跳到下标 j 需要满足:arr[i] > arr[j] 且 arr[i] > arr[k] ,其中下标 k 是所有 i 到 j 之间的数字(更正式的,min(i, j) < k < max(i, j))。
你可以选择数组的任意下标开始跳跃。请你返回你最多可以访问多少个下标。
利用动态规划的思想,令dp[i]为从位置i开始所能访问的最大下标数,则动态规划的递推式为:
\(dp[i] = max(dp[i],dp[j]+1)\),其中j为位置i可达点的下标。
其实,想出动态规划的递推式不难,关键在于我们怎么保证在计算dp[i]时,dp[j]可知。明显的,在数组中,我们在最低的点没有办法进行跳跃,则从该索引i出发最多访问1个下标;那么,我们再从第二低的点出现,此时,该点要么无法跳跃,要么只能跳最低的点,而此时\(dp[i]=1\)。由此可知,我们将整个数组从最小值开始遍历,到最大值,即可保证为全局最佳解。而这,与我们平时的从左到右的遍历不同,也是该问题的关键点了。
class Solution:
def maxJumps(self, arr, d) :
index_num = list(enumerate(arr))
index_num.sort(key = lambda x:x[1])
n = len(arr)
dp = [1 for i in range(n)]
res = 1
for index,num in index_num:
for i in reversed(range(max(0,index-d),index)):
if arr[i] >= num:
break
dp[index] = max(dp[index],dp[i]+1)
for i in range(index+1,min(index+d+1,n)):
if arr[i] >= num:
break
dp[index] = max(dp[index],dp[i]+1)
res = max(res,dp[index])
return res
标签:index,arr,Contest,res,self,174,root,Leetcode,dp 来源: https://www.cnblogs.com/hellojamest/p/12253657.html