ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[Leetcode Weekly Contest]174

2020-02-02 21:03:19  阅读:281  来源: 互联网

标签:index arr Contest res self 174 root Leetcode dp


链接: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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有