[Leetcode Weekly Contest]174

Posted Jamest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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

以上是关于[Leetcode Weekly Contest]174的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode(Weekly Contest 183)题解

LeetCode(Weekly Contest 187)题解

LeetCode笔记:Weekly Contest 297

LeetCode笔记:Weekly Contest 301

LeetCode笔记:Weekly Contest 317

LeetCode笔记:Weekly Contest 288