leetcode weekly contest 339
第四题的换根 dp
还是比较难的题目,最后一题典型的跳跃问题,确实比较难的题目
2609. 最长平衡子字符串
给你一个仅由 0
和 1
组成的二进制字符串 s
。
如果子字符串中 所有的 0
都在 1
之前 且其中 0
的数量等于 1
的数量,则认为 s
的这个子字符串是平衡子字符串。请注意,空子字符串也视作平衡子字符串。
返回 s
中最长的平衡子字符串长度。
子字符串是字符串中的一个连续字符序列。
示例 1:
输入:s = "01000111" |
示例 2:
输入:s = "00111" |
示例 3:
输入:s = "111" |
提示:
1 <= s.length <= 50
'0' <= s[i] <= '1'
地址
https://leetcode.cn/contest/weekly-contest-338/problems/k-items-with-the-maximum-sum/
题意
直接枚举
思路
- 枚举所有可能的子字符串并检测该字符串是否符合平衡即可。我们找到连续 $0$ 的最大长度,并求出后续的 $1$ 的长度,如果 $0$ 的长度小于当前 $0$ 的长度,则可能构成平衡字符串。
- 复杂度分析:
- 时间复杂度:$O(n)$。
- 空间复杂度:$O(1)$。
代码
class Solution { |
2610. 转换二维数组
给你一个整数数组 nums
。请你创建一个满足以下条件的二维数组:
- 二维数组应该 只 包含数组
nums
中的元素。 - 二维数组中的每一行都包含 不同 的整数。
- 二维数组的行数应尽可能 少 。
返回结果数组。如果存在多种答案,则返回其中任何一种。
请注意,二维数组的每一行上可以存在不同数量的元素。
示例 1:
输入:nums = [1,3,4,1,2,3,1] |
示例 2:
输入:nums = [1,2,3,4] |
提示:
1 <= nums.length <= 200
1 <= nums[i] <= nums.length
地址
https://leetcode.cn/problems/convert-an-array-into-a-2d-array-with-conditions/
题意
贪心
思路
- 题目比较简单,由于每行都不能存在重复的元素,因此不可能只统计数组中每个元素的出现次数,每次构造时从不相同的元素中挑选一个即可。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 为数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 为数组的长度。
代码
class Solution { |
2611. 老鼠和奶酪
有两只老鼠和 n
块不同类型的奶酪,每块奶酪都只能被其中一只老鼠吃掉。
下标为 i
处的奶酪被吃掉的得分为:
- 如果第一只老鼠吃掉,则得分为
reward1[i]
。 - 如果第二只老鼠吃掉,则得分为
reward2[i]
。
给你一个正整数数组 reward1
,一个正整数数组 reward2
,和一个非负整数 k
。
请你返回第一只老鼠恰好吃掉 k
块奶酪的情况下,最大 得分为多少。
示例 1:
输入:reward1 = [1,1,3,4], reward2 = [4,4,1,1], k = 2 |
示例 2:
输入:reward1 = [1,1], reward2 = [1,1], k = 2 |
提示:
1 <= n == reward1.length == reward2.length <= 105
1 <= reward1[i], reward2[i] <= 1000
0 <= k <= n
地址
https://leetcode.cn/contest/weekly-contest-339/problems/mice-and-cheese/
题意
贪心
思路
- 由于第一只老鼠必须要吃 $k$ 个奶酪,可以证明贪心原则,奶酪给第一个老鼠吃得分为 $r_1[i]$,给第二个奶酪吃得分为 $r_2[i]$ ,则此时差距为 $diff[i] = r_1[i] - r_2[i]$,由于必须选择 $k$ 个,因此我们尽量选择 $diff[i]$ 最大的即可。
- 复杂度分析:
- 时间复杂度:$O(n \log n)$,其中 $n$ 为数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 为数组的长度。
代码
class Solution { |
2612. 最少翻转操作数
给你一个整数 n
和一个在范围 [0, n - 1]
以内的整数 p
,它们表示一个长度为 n
且下标从 0 开始的数组 arr
,数组中除了下标为 p
处是 1
以外,其他所有数都是 0
。
同时给你一个整数数组 banned
,它包含数组中的一些位置。banned
中第 i 个位置表示 arr[banned[i]] = 0
,题目保证 banned[i] != p
。
你可以对 arr
进行 若干次 操作。一次操作中,你选择大小为 k
的一个 子数组 ,并将它 翻转 。在任何一次翻转操作后,你都需要确保 arr
中唯一的 1
不会到达任何 banned
中的位置。换句话说,arr[banned[i]]
始终 保持 0
。
请你返回一个数组 ans
,对于 [0, n - 1]
之间的任意下标 i
,ans[i]
是将 1
放到位置 i
处的 最少 翻转操作次数,如果无法放到位置 i
处,此数为 -1
。
- 子数组 指的是一个数组里一段连续 非空 的元素序列。
- 对于所有的
i
,ans[i]
相互之间独立计算。 - 将一个数组中的元素 翻转 指的是将数组中的值变成 相反顺序 。
示例 1:
输入:n = 4, p = 0, banned = [1,2], k = 4 |
示例 2:
输入:n = 5, p = 0, banned = [2,4], k = 3 |
示例 3:
输入:n = 4, p = 2, banned = [0,1,3], k = 1 |
提示:
1 <= n <= 105
0 <= p <= n - 1
0 <= banned.length <= n - 1
0 <= banned[i] <= n - 1
1 <= k <= n
banned[i] != p
banned
中的值 互不相同 。
地址
https://leetcode.cn/contest/weekly-contest-339/problems/minimum-reverse-operations/
题意
广度优先搜索
思路
- 题目本身比较难的题目,关键在于理解翻转的思路,本质为一个跳跃游戏类似的题目,但跳跃的距离较远,参考题解即可,关键的思路如下:
- 区间 $[l,r]$ 内关 $x$ 的反转为 $l + r - x$;
- 我们每次向左移动 $1$ 时,反转的下标会减少 $2$;
- 我们每次向右移动 $1$ 时,反转的下标会减少 $2$;
- 反转本质即相当于跳跃,
- 如 $k$ 为偶数,则反转后也只能跳转到与当前奇偶不同的位置上,即此时 $i$ 只能反转到 $i + 1, i + 3, \cdots$ 等位置上;
- 如 $k$ 为奇数,则反转后也只能跳转到与当前奇偶相同的位置上,即此时 $i$ 只能反转到 $i + 2, i + 4, \cdots$ 等位置上;
- 我们用$bfs$ 来标记所有被跳跃过的位置,假设当前的位置处于 $x$ 处,则此时它可以跳跃的范围为 $A = [\max(x - k + 1, k - x - 1), \min(x + k - 1, 2 * n - k - x - 1)]$,然后将当前仍然处在 $A$ 区域的位置全部删除即可,按照层次遍历即可。确实是非常不错的题目,感觉比较新颖的题目。
- 复杂度分析:
- 时间复杂度:$O(n \log n)$,其中 $n$ 为数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 为数组的长度。
代码
class Solution { |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://whistle-wind.com/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章