leetcode 第 174 场周赛 - 解答 python 版

本周周赛还是比较简单。

5328.方阵中战斗力最弱的 K 行

水题,数组排序,

https://leetcode-cn.com/conte...

需要返回 1 最少的前 k 行,1 一样多的先返回下标小的

  1. 统计每行有几个 1。
  2. 排序
  3. 返回前 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...

  1. 先求数组长度。
  2. 再求数组中每个元素出现的次数。
  3. 对次数排序
  4. 从大到小遍历,依次累加,直到超过长度的一半
  5. 返回累加了几个数
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/刷题/

你可能感兴趣的:(leetcode,python)