leetcode weekly contes 370
本周的题目质量比较高,需要仔细花心思与时间来作对的题目。
100115. 找到冠军 I
一场比赛中共有 n
支队伍,按从 0
到 n - 1
编号。
给你一个下标从 0 开始、大小为 n * n
的二维布尔矩阵 grid
。对于满足 0 <= i, j <= n - 1
且 i != j
的所有 i, j
:如果 grid[i][j] == 1
,那么 i
队比 j
队 强 ;否则,j
队比 i
队 强 。
在这场比赛中,如果不存在某支强于 a
队的队伍,则认为 a
队将会是 冠军 。
返回这场比赛中将会成为冠军的队伍。
示例 1:
输入:grid = [[0,1],[0,0]] |
示例 2:
输入:grid = [[0,0,1],[1,0,1],[0,0,0]] |
提示:
n == grid.length
n == grid[i].length
2 <= n <= 100
grid[i][j]
的值为0
或1
- 对于满足
i != j
的所有i, j
,grid[i][j] != grid[j][i]
均成立 - 生成的输出满足:如果
a
队比b
队强,b
队比c
队强,那么a
队比c
队强
地址
https://leetcode.cn/contest/weekly-contest-370/problems/find-champion-i/
题意
模拟
思路
- 直接检测每一行中是否全部都为 $n - 1$ 时,则表示第 $i$ 队比其他队都强。
- 复杂度分析:
- 时间复杂度:$O(n^2)$,其中 $n$ 表示给定的数组的长度。
- 空间复杂度:$O(1)$。
代码
class Solution: |
100116. 找到冠军 II
一场比赛中共有 n
支队伍,按从 0
到 n - 1
编号。每支队伍也是 有向无环图(DAG) 上的一个节点。
给你一个整数 n
和一个下标从 0 开始、长度为 m
的二维整数数组 edges
表示这个有向无环图,其中 edges[i] = [ui, vi]
表示图中存在一条从 ui
队到 vi
队的有向边。
从 a
队到 b
队的有向边意味着 a
队比 b
队 强 ,也就是 b
队比 a
队 弱 。
在这场比赛中,如果不存在某支强于 a
队的队伍,则认为 a
队将会是 冠军 。
如果这场比赛存在 唯一 一个冠军,则返回将会成为冠军的队伍。否则,返回 -1
。
注意
- 环 是形如
a1, a2, ..., an, an+1
的一个序列,且满足:节点a1
与节点an+1
是同一个节点;节点a1, a2, ..., an
互不相同;对于范围[1, n]
中的每个i
,均存在一条从节点ai
到节点ai+1
的有向边。 - 有向无环图 是不存在任何环的有向图。
示例 1:
输入:n = 3, edges = [[0,1],[1,2]] |
示例 2:
输入:n = 4, edges = [[0,2],[1,3],[1,2]] |
提示:
1 <= n <= 100
m == edges.length
0 <= m <= n * (n - 1) / 2
edges[i].length == 2
0 <= edge[i][j] <= n - 1
edges[i][0] != edges[i][1]
- 生成的输入满足:如果
a
队比b
队强,就不存在b
队比a
队强 - 生成的输入满足:如果
a
队比b
队强,b
队比c
队强,那么a
队比c
队强
地址
https://leetcode.cn/contest/weekly-contest-370/problems/find-champion-ii/
题意
图论
思路
- 题目需要找是否存在一个队比其他队都强,实则找到入度为 $0$ 的节点即可,因为只有入度为 $0$ 的节点才不会有其他队比它强。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示给定的节点的数目。
- 空间复杂度:$O(1)$。
代码
class Solution: |
100118. 在树上执行操作以后得到的最大分数
有一棵 n
个节点的无向树,节点编号为 0
到 n - 1
,根节点编号为 0
。给你一个长度为 n - 1
的二维整数数组 edges
表示这棵树,其中 edges[i] = [ai, bi]
表示树中节点 ai
和 bi
有一条边。
同时给你一个长度为 n
下标从 0 开始的整数数组 values
,其中 values[i]
表示第 i
个节点的值。
一开始你的分数为 0
,每次操作中,你将执行:
- 选择节点
i
。 - 将
values[i]
加入你的分数。 - 将
values[i]
变为0
。
如果从根节点出发,到任意叶子节点经过的路径上的节点值之和都不等于 0 ,那么我们称这棵树是 健康的 。
你可以对这棵树执行任意次操作,但要求执行完所有操作以后树是 健康的 ,请你返回你可以获得的 最大分数 。
示例 1:
输入:edges = [[0,1],[0,2],[0,3],[2,4],[4,5]], values = [5,2,5,2,1,1] |
示例 2:
输入:edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]], values = [20,10,9,7,4,3,5] |
提示:
2 <= n <= 2 * 104
edges.length == n - 1
edges[i].length == 2
0 <= ai, bi < n
values.length == n
1 <= values[i] <= 109
- 输入保证
edges
构成一棵合法的树。
地址
https://leetcode.cn/problems/maximum-score-after-applying-operations-on-a-tree/description/
题意
动态规划
思路
- 题目有点绕,但实际比较简单,我们知道仔细分析一下两种情况,假设当前遍历的节点为 $x$, 则可以看到:
- 假设 $x$ 的祖先存在某些节点未操作,即保存在树中,由于节点的每个值都大于 $0$, 此时以 $x$ 为根节点的子树中的所有节点均可以操作,此时直接返回该子树下所有节点的和 $sum(x)$ 即可;
- 假设 $x$ 的祖先节点全部都被操作, 此时以 $x$ 为根节点的子树中必须有节点需要保存,分为两种情况:
- 如果 $x$ 为叶子节点,则该节点一定需要保存,一定不能操作;
- 如果 $x$ 为非叶子节点,则我们返回 $x$ 被操作后的子树的最大值与 $x$ 不被操作的最大值即可;
- 实际我们需要两个 $DFS$ 接口,第一遍 $DFS$ 求出以 $x$ 为根节点的子树的元素和,第二遍我们求出以 $0$ 为节点的树中两种不同操作情况下的最大值即可。
- 时间复杂度:$O(n)$,其中$n$ 表示数组的长度;
- 空间复杂度:$O(1)$;
代码
class Solution: |
100112. 平衡子序列的最大和
给你一个下标从 0 开始的整数数组 nums
。
nums
一个长度为 k
的 子序列 指的是选出 k
个 下标 i0 < i1 < ... < ik-1
,如果这个子序列满足以下条件,我们说它是 平衡的 :
- 对于范围
[1, k - 1]
内的所有j
,nums[ij] - nums[ij-1] >= ij - ij-1
都成立。
nums
长度为 1
的 子序列 是平衡的。
请你返回一个整数,表示 nums
平衡 子序列里面的 最大元素和 。
一个数组的 子序列 指的是从原数组中删除一些元素(也可能一个元素也不删除)后,剩余元素保持相对顺序得到的 非空 新数组。
示例 1:
输入:nums = [3,3,5,6] |
示例 2:
输入:nums = [5,-1,-3,8] |
示例 3:
输入:nums = [-2,-1] |
提示:
1 <= nums.length <= 105
-109 <= nums[i] <= 109
地址
https://leetcode.cn/contest/weekly-contest-370/problems/maximum-balanced-subsequence-sum/
题意
线段树
思路
题目还是比较不错的题目,主要是自己想复杂了,想到了 $LIS$ 问题了,实际要简单不少。题目要求: $nums[i_j] - nums[i_{j-1}] \ge i_j - i_{j-1}$, 将上述变形即为 $nums[i_j] - i_j \ge nums[i_{j-1}]- i_{j-1}$, 本质上我们需要在满足 $f[i] = nums[i] - i$ 递增的序列中找到 $nums[i]$ 的和的最大值。我们令 $dp[i]$ 表示第 $i$ 个元素为 $f[i]$ 为递增的子序列中的元素的最大和,此时我们可以知道递推公式可以知道 :
$$dp[i+1] = \max(dp[j])_{j=0}^{i} + nums[i+1] \quad if \quad nums[i+1] - (i + 1) \ge nums[j] -j $$
刚开始想到了线段树,由于 $nums[i] - i$ 的值是固定的,最多只有 $n$ 个,此时我们进行离散化,假设当前 $b[i] = nums[i] - i$,此时找到 $0,k$ 范围的更新值进行更新,此时当前 $dp[i+1] = max(dp[0,\cdots k]) + nums[i+1]$,此时更新即可,不用范围更新就比较简单了,详细可以参考代码。
复杂度分析:
- 时间复杂度:$O(n \log n)$,其中 $n$ 表示数组的长度,线段树的查询和更新的复杂度均为 $n \log n$;
- 空间复杂度:$O(n)$,其中 $n$ 表示数组的长度;
代码
|
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://whistle-wind.com/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章