leetcode contest 299
前三题基本上都是套路题了,第四题还是有点难度。
2319. 判断矩阵是否是一个 X 矩阵
题目
如果一个正方形矩阵满足下述 全部 条件,则称之为一个 X
矩阵 :
矩阵对角线上的所有元素都 不是 0
矩阵中所有其他元素都是 0
给你一个大小为 n x n
的二维整数数组 grid
,表示一个正方形矩阵。如果 grid
是一个 X
矩阵 ,返回 true
;否则,返回 false 。
示例 1:
输入:grid = [[2,0,0,1],[0,3,1,0],[0,5,2,0],[4,0,0,2]] |
示例 2:
输入:grid = [[5,7,0],[0,3,1],[0,5,0]] |
提示:
n == grid.length == grid[i].length
3 <= n <= 100
0 <= grid[i][j] <= 105
地址
https://leetcode.cn/contest/weekly-contest-299/problems/check-if-matrix-is-x-matrix/
题意
直接遍历
思路
- 直接遍历判断对角线元素和非对角线元素的值即可。
- 复杂度分析:
- 时间复杂度:$O(n^2)$, 其中 $n$ 为矩阵的行数。
- 空间复杂度:$O(1)$。
代码
class Solution { |
2320. 统计放置房子的方式数
题目
一条街道上共有 n * 2
个 地块 ,街道的两侧各有 n
个地块。每一边的地块都按从 1
到 n
编号。每个地块上都可以放置一所房子。
- 现要求街道同一侧不能存在两所房子相邻的情况,请你计算并返回放置房屋的方式数目。由于答案可能很大,需要对
109 + 7
取余后再返回。
注意,如果一所房子放置在这条街某一侧上的第 i 个地块,不影响在另一侧的第 i 个地块放置房子。
示例 1:
输入:n = 1 |
示例 2:
输入:n = 2 |
提示:
1 <= n <= 104
地址
https://leetcode.cn/contest/weekly-contest-299/problems/count-number-of-ways-to-place-houses/
题意
动态规划
思路
- 简单的动态规划,设 $x = {0,1,2,3}$ 分别表示道路两侧的房子的状态,则递推公式如下:
$$
dp[i][0] = (dp[i-1][0] + dp[i-1][1] + dp[i-1][2] + dp[i-1][3]) \
dp[i][1] = (dp[i-1][0] + dp[i-1][2]) \
dp[i][2] = (dp[i-1][0] + dp[i-1][1]) \
dp[i][3] = (dp[i-1][0]) \
$$ - 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 为街道地块的数目。
- 空间复杂度:$O(n)$,其中 $n$ 为街道地块的数目。
代码
class Solution { |
2321. 拼接数组的最大分数
题目
给你两个下标从 0
开始的整数数组 nums1
和 nums2
,长度都是 n 。
你可以选择两个整数 left
和 right
,其中 0 <= left <= right < n
,接着 交换 两个子数组 nums1[left...right]
和 nums2[left...right]
。
例如,设 nums1 = [1,2,3,4,5]
和 nums2 = [11,12,13,14,15]
,整数选择 left = 1
和 right = 2
,那么 nums1
会变为 [1,12,13,4,5]
而 nums2
会变为 [11,2,3,14,15]
。
你可以选择执行上述操作 一次 或不执行任何操作。
数组的 分数 取 sum(nums1)
和 sum(nums2)
中的最大值,其中 sum(arr)
是数组 arr
中所有元素之和。
返回 可能的最大分数 。
子数组 是数组中连续的一个元素序列。arr[left...right]
表示子数组包含 nums
中下标 left
和 right
之间的元素(含 下标 left
和 right
对应元素)。
示例 1:
输入:nums1 = [60,60,60], nums2 = [10,90,10] |
示例 2:
输入:nums1 = [20,40,20,70,30], nums2 = [50,20,50,40,20] |
示例 3:
输入:nums1 = [7,11,13], nums2 = [1,1,1] |
提示:
n == nums1.length == nums2.length
1 <= n <= 105
1 <= nums1[i], nums2[i] <= 104
地址
https://leetcode.cn/contest/weekly-contest-299/problems/maximum-score-of-spliced-array/
题意
最长连续子数组和
思路
- 仔细一看结果是最长连续子数组和的变形,我们设数组 $arr1$ 为 $[{nums2}[0]-\textit{nums1}[0], {nums2}[1]-\textit{nums1}[1], {nums2}[2]-\textit{nums1}[2], {nums2}[3]-\textit{nums1}[3], \cdots]$。我们只需要找到数组 $arr1$ 中的最大的连续子数组和 即可,然后将最大的子数组和加上 $nums1$ 的和,即为将数组 $2$ 替换数组 $1$ 的最大分数,同理我们可以求出数组 $1$ 替换 数组 $2$ 的最大分数。
- 复杂度分析:
- 时间复杂度:$O(n)$, $n$ 表示数组的长度。
- 空间复杂度:$O(n)$,$n$ 表示数组的长度。
代码
class Solution { |
2322. 从树中删除边的最小分数
题目
存在一棵无向连通树,树中有编号从 0
到 n - 1
的 n
个节点, 以及 n - 1
条边。
给你一个下标从 0
开始的整数数组 nums
,长度为 n
,其中 nums[i]
表示第 i
个节点的值。另给你一个二维整数数组 edges
,长度为 n - 1
,其中 edges[i] = [ai, bi]
表示树中存在一条位于节点 ai
和 bi
之间的边。
删除树中两条 不同 的边以形成三个连通组件。对于一种删除边方案,定义如下步骤以计算其分数:
- 分别获取三个组件 每个 组件中所有节点值的异或值。
- 最大 异或值和 最小 异或值的 差值 就是这一种删除边方案的分数。
例如,三个组件的节点值分别是:[4,5,7]
、[1,9]
和[3,3,3]
。三个异或值分别是4 ^ 5 ^ 7 = 6、1 ^ 9 = 8
和3 ^ 3 ^ 3 = 3
。最大异或值是8
,最小异或值是3
,分数是8 - 3 = 5
。
返回在给定树上执行任意删除边方案可能的 最小 分数。
示例 1:
输入:nums = [1,5,5,4,11], edges = [[0,1],[1,2],[1,3],[3,4]] |
示例 2:
输入:nums = [5,5,2,4,4,2], edges = [[0,1],[1,2],[5,2],[4,3],[1,3]] |
提示:
n == nums.length
3 <= n <= 1000
1 <= nums[i] <= 108
edges.length == n - 1
edges[i].length == 2
0 <= ai, bi < n
ai != bi
edges
表示一棵有效的树
地址
https://leetcode.cn/contest/weekly-contest-299/problems/minimum-score-after-removals-on-a-tree/
题意
深度优先搜索
思路
- 题目非常有意思的说,我们枚举所有可能的两条边即可:
- 我们首先求出所有节点的异或的值为 $tot$;
- 设 $dp[x][y]$ 表示去掉节点 $x$ 且以节点 $y$ 为根节点的子树所有节点异或的值;
- 我们依次枚举去掉 $x$ 且以节点为 $y$ 为根节点的子树中依次去掉一条变 $[a,b]$,此时整个树被分为三部分:
- 以 $y$ 为根节点的子树的节点所有值的异或 $dp[x][y]$;
- 以 $b$ 为根节点的子树的节点所有值的异或 $dp[a][b]$;
- 剩余的部分的节点的值异或为 $tot \oplus dp[x][y] \oplus dp[a][b]$;
- 此时我们即可获分数为:$\max (dp[x][y],dp[a][b], tot \oplus dp[x][y] \oplus dp[a][b]) - \min (dp[x][y],dp[a][b], tot \oplus dp[x][y] \oplus dp[a][b])$。
- 枚举所有的可能即可。
- 复杂度分析:
- 时间复杂度:$n^2$, $n$ 表示节点的数目。
- 空间复杂度:$n^2$, $n$ 表示节点的数目。
代码
class Solution { |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://mikemeng.org/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章