leetcode-第 174 场周赛

第一次参加比赛,结果比想象的好,还以为自己可能一道题都做不出,但看了大佬们的排名,哎。。。。

第一题:方阵中战斗力最弱的 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]
解释:
每行中的军人数目:
行 0 -> 2 
行 1 -> 4 
行 2 -> 1 
行 3 -> 2 
行 4 -> 5 
从最弱到最强对这些行排序后得到 [2,0,3,1,4]

思路:

1.统计每行1的个数存入字典

2.对字典进行排序

知识点整理:

sorted 不会改变原数组的顺序

根据自定义规则来排序:

根据长度

sorted(chars,key=lambda x:len(x))

Out[92]: ['a', 'is', 'boy', 'bruce', 'handsome']

根据第几个字段

tuple_list = [('A', 1,5), ('B', 3,2), ('C', 2,6)]

#key=lambda x: x[1]中可以任意选定x中可选的位置进行排序

sorted(tuple_list, key=lambda x: x[1])

根据第几个属性

class tuple_list:

 def __init__(self, one, two, three):

  self.one = one

  self.two = two

  self.three = three

 def __repr__(self):

  return repr((self.one, self.two, self.three))

tuple_list_ = [tuple_list('C', 1,5), tuple_list('A', 3,2), tuple_list('C', 2,6)]

# 首先根据one的位置来排序,然后根据two的位置来排序

sorted(tuple_list_, key=lambda x:(x.one, x.two))

Out[112]: [('A', 3, 2), ('C', 1, 5), ('C', 2, 6)]

时间,空间:o(nlogn) o(n)

class Solution:
    def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
        d={}
        for i in range(len(mat)):
            d[i] = sum(mat[i])
        d = sorted(d.items(), key=lambda x:x[1])
        res = []
        for one in d:
            res.append(one[0])
        return res[0:k]

class Solution(object):
    def kWeakestRows(self, mat, k):
        """
        :type mat: List[List[int]]
        :type k: int
        :rtype: List[int]
        """
        tmp = []
        res = []
        for i,r in enumerate(mat):
            tmp.append([sum(r),i])
        tmp.sort()
        for one in tmp:
            res.append(one[1])
        return res[:k]
#看看人家的代码简直就是艺术......
class Solution(object):
    def kWeakestRows(self, mat, k):
        A = [[sum(r), i] for i,r in enumerate(mat)]
        A.sort()
        return [i for s,i in A][:k]

第二题:数组大小减半

给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。

返回 至少 能删除数组中的一半整数的整数集合的最小大小。

输入:arr = [3,3,3,3,5,5,5,2,2,7]
输出:2
解释:选择 {3,7} 使得结果数组为 [5,5,5,2,2]、长度为 5(原数组长度的一半)。
大小为 2 的可行集合有 {3,5},{3,2},{5,2}。
选择 {2,7} 是不可行的,它的结果数组为 [3,3,3,3,5,5,5],新数组长度大于原数组的二分之一。

思路:

先遍历一次数组统计每个数字的次数,然后对这个存储排序(根据次数字段),然后依次减去次数直到数组长度小于一半。

class Solution(object):
    def minSetSize(self, arr):
        """
        :type arr: List[int]
        :rtype: int
        """
        if not arr:
            return 0
        d = {}
        for one in arr:
            if one in d:
                d[one] += 1
            else:
                d[one] = 1
        l = sorted(d.items(), key=lambda x:x[1], reverse=True)
        tmp = 0
        count = 0
        for one in l:
            tmp +=one[1]
            count += 1
            if tmp >= len(arr)//2:
                return count 
                
                

第三题:分裂二叉树的最大乘积

给你一棵二叉树,它的根为 root 。请你删除 1 条边,使二叉树分裂成两棵子树,且它们子树和的乘积尽可能大。

由于答案可能会很大,请你将结果对 10^9 + 7 取模后再返回

思路:

定义一个空间存储每个节点下的和,如上图节点2的和是11,然后遍历每个节点即可。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def maxProduct(self, root: TreeNode) -> int:
        def get_sum(root):
            if not root:
                return 0
            ret=root.val+get_sum(root.left)+get_sum(root.right)
            mem[root]=ret
            return ret
        mem={}
        _sum=get_sum(root)
        ret=0
        for k in mem:
            ret=max(ret,(_sum-mem[k])*mem[k])
        return ret%(10**9+7)
        

第四题:跳跃游戏 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转移是dp[i] = max(dp[i], dp[j] + 1)

至于这里为什么要先排序呢,因为,当前坐标的dp值要依赖于比其更低坐标处的dp值,所以先排序,优先计算值小的坐标

class Solution(object):
    def maxJumps(self, A, d):
        n = len(A)
        dp = [1] * n
        B = sorted([a, i] for i, a in enumerate(A))
        for a, i in B:
            j = i - 1
            while j >= 0 and A[j] < A[i] and i - j <= d:
                dp[i] = max(dp[i], dp[j] + 1)
                j -= 1
            j = i + 1
            while j < n and A[j] < A[i] and j - i <= d:
                dp[i] = max(dp[i], dp[j] + 1)
                j += 1
        return max(dp)
发布了155 篇原创文章 · 获赞 17 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_36328915/article/details/104143299