leetcode biweekly contest 94
第四题就是模板题目,太没什么新意了,第三题时个贪心的数论的题目还算比较有新意的题目。
6273. 最多可以摧毁的敌人城堡数目
给你一个长度为 n
,下标从 0 开始的整数数组 forts
,表示一些城堡。forts[i]
可以是 -1
,0
或者 1
,其中:
-1
表示第i
个位置 没有 城堡。0
表示第i
个位置有一个 敌人 的城堡。1
表示第i
个位置有一个你控制的城堡。
现在,你需要决定,将你的军队从某个你控制的城堡位置 i
移动到一个空的位置 j
,满足:
0 <= i, j <= n - 1
- 军队经过的位置 只有 敌人的城堡。正式的,对于所有
min(i,j) < k < max(i,j)
的k
,都满足forts[k] == 0
。
当军队移动时,所有途中经过的敌人城堡都会被 摧毁 。
请你返回 最多 可以摧毁的敌人城堡数目。如果 无法 移动你的军队,或者没有你控制的城堡,请返回 0
。
示例 1:
输入:forts = [1,0,0,-1,0,0,0,0,1] |
示例 2:
输入:forts = [0,0,1,-1] |
提示:
1 <= forts.length <= 1000
-1 <= forts[i] <= 1
地址
https://leetcode.cn/contest/biweekly-contest-94/problems/maximum-enemy-forts-that-can-be-captured/
题意
直接遍历
思路
- 由于移动方向可以有两种,那么从左到右移动,要么从右向左移动,我们需要找到一段连续的区间,起点为 $1$,终点为 $-1$,且中间的位置全部为 $0$,找到这样的最长的连续区间即可。
- 复杂度分析:
- 时间复杂度:$O(n)$。其中 $n$ 表示数组的长度。
- 空间复杂度:$O(1)$。
代码
class Solution { |
6274. 奖励最顶尖的 K 名学生
给你两个字符串数组 positive_feedback
和 negative_feedback
,分别包含表示正面的和负面的词汇。不会 有单词同时是正面的和负面的。
一开始,每位学生分数为 0
。每个正面的单词会给学生的分数 加 3
分,每个负面的词会给学生的分数 减 1
分。
给你 n
个学生的评语,用一个下标从 0 开始的字符串数组 report
和一个下标从 0 开始的整数数组 student_id
表示,其中 student_id[i]
表示这名学生的 ID ,这名学生的评语是 report[i]
。每名学生的 ID 互不相同。
给你一个整数 k
,请你返回按照得分 从高到低 最顶尖的 k
名学生。如果有多名学生分数相同,ID 越小排名越前。
示例 1:
输入:positive_feedback = ["smart","brilliant","studious"], negative_feedback = ["not"], report = ["this student is studious","the student is smart"], student_id = [1,2], k = 2 |
示例 2:
输入:positive_feedback = ["smart","brilliant","studious"], negative_feedback = ["not"], report = ["this student is not studious","the student is smart"], student_id = [1,2], k = 2 |
提示:
1 <= positive_feedback.length, negative_feedback.length <= 104
1 <= positive_feedback[i].length, negative_feedback[j].length <= 100
positive_feedback[i]
和negative_feedback[j]
都只包含小写英文字母。positive_feedback
和negative_feedback
中不会有相同单词。n == report.length == student_id.length
1 <= n <= 104
report[i]
只包含小写英文字母和空格' '
。report[i]
中连续单词之间有单个空格隔开。1 <= report[i].length <= 100
1 <= student_id[i] <= 109
student_id[i]
的值 互不相同 。1 <= k <= n
地址
https://leetcode.cn/contest/biweekly-contest-94/problems/reward-top-k-students/
题意
哈希表
思路
- 题目比较简单的哈希映射即可。首先我们对每个单词求出其对应的分数。接着我们遍历每个人对应的报告,并将其报告中的每个单词切割出来,对每个单词求其分数。如果该单词为正面单词,则其得分加上 $3$,如果该单词为负面单词,则其得分减去 $3$,最后求出每个人的总得分,按照题目要求取最大的 $k$ 个得分的 $ID$ 即可。
- 复杂度分析:
- 时间复杂度:$O(nm + n\log n)$,其中 $n$ 为给定的学生的人数,$m$ 表示每个同学的句子的长度。先遍历求出每个学生的得分,然后利用排序求出 $topk$ 即可。
- 空间复杂度:$O(n)$。
代码
class Solution { |
6295. 最小化两个数组中的最大值
给你两个数组 arr1
和 arr2
,它们一开始都是空的。你需要往它们中添加正整数,使它们满足以下条件:
arr1
包含uniqueCnt1
个 互不相同 的正整数,每个整数都 不能 被divisor1
整除 。arr2
包含uniqueCnt2
个 互不相同 的正整数,每个整数都 不能 被divisor2
整除 。arr1
和arr2
中的元素 互不相同 。
给你 divisor1
,divisor2
,uniqueCnt1
和 uniqueCnt2
,请你返回两个数组中 最大元素 的 最小值 。
示例 1:
输入:divisor1 = 2, divisor2 = 7, uniqueCnt1 = 1, uniqueCnt2 = 3 |
示例 2:
输入:divisor1 = 3, divisor2 = 5, uniqueCnt1 = 2, uniqueCnt2 = 1 |
示例 3:
输入:divisor1 = 2, divisor2 = 4, uniqueCnt1 = 8, uniqueCnt2 = 2 |
提示:
2 <= divisor1, divisor2 <= 105
1 <= uniqueCnt1, uniqueCnt2 < 109
2 <= uniqueCnt1 + uniqueCnt2 <= 109
地址
https://leetcode.cn/contest/biweekly-contest-94/problems/minimize-the-maximum-of-two-arrays/
题意
贪心
思路
- 这个题目稍微有点意思,假如我们直接求最小数的话似乎不太好求,但是我们自然而然的会想到用二分法,假设当前的最大数为 $x$,我们只需要求出所有小于等于 $x$ 的元素中符合题要求的元素数目大于等于 $uniqueCnt1 + uniqueCnt2$ 即可,采用逼近法即可求出最小的 $x$。首先我们需要分析一下数的关系:
- 所有不能被 $divisor1$ 整除的元素都可以作为 $arr1$ 的元素;
- 所有不能被 $divisor2$ 整除的元素都可以作为 $arr2$ 的元素;
- $arr1$ 与 $arr2$ 都不能包含既能被 $divisor1$ 整除又能被 $divisor2$ 整除的元素;
- 我们知道给定的上限为 $x$,则可以知道:
- 所有小于等于 $x$ 且能被 $divisor1$ 整除的元素数目为 $c_1 =\dfrac{x}{divisor1}$;
- 所有小于等于 $x$ 且能被 $divisor2$ 整除的元素数目为 $c_2 = \dfrac{x}{divisor2}$;
- 所有小于等于 $x$ 且能被 $divisor1$ 又能被 $divisor2$ 整除的元素数目为 $c_3 = \dfrac{x}{lcm(divisor1,divisor2)}$, 其中 $lcm(divisor1,divisor2) = \dfrac{divisor1 \times divisor2}{\gcd(divisor1,divisor2)}$,表示二者的最小公倍数。
- 根据贪心原则,首先我们应该剔除所有能被二者整除的元素,即剔除掉 $c_3$,此时还剩下 $x-c_3$ 个元素;
- 所有能被 $divisor1$ 整除但不能被 $divisor2$ 整除的元素都可以放到 $arr2$ 中,其数目为 $c_1 - c_3$;所有能被 $divisor2$ 整除但不能被 $divisor1$ 整除的元素都可以放到 $arr1$ 中,其数目为 $c_2-c_3$,此时 $arr1$ 还需要从小于等于 $x$ 的元素中取出 $uniqueCnt1 - (c_2-c_3)$ 个元素,$arr2$ 还需要从小于等于 $x$ 的元素中取出 $uniqueCnt2 - (c_1-c_3)$ 个元素,此时只需要满足剩下的元素能够被二者全部取到即可。此时需要满足的条件为:
$$
x - c_1 - c_2 + c_3 \ge \textit{uniqueCnt1} - (c_2-c_3) + uniqueCnt2 - (c_1-c_3)\
$$ - 我们只需要利用上述的规则找到最小的 $x$ 即可,即为满足题目要求的最大元素的最小值。
- 复杂度分析
- 时间复杂度:时间复杂度为 $O(\log n)$,$n$ 表示给定元素的最大数目。
- 空间复杂度:时间复杂度为 $O(1)$。
代码
class Solution { |
6276. 统计同位异构字符串数目
给你一个字符串 s
,它包含一个或者多个单词。单词之间用单个空格 ' '
隔开。
如果字符串 t
中第 i
个单词是 s
中第 i
个单词的一个 排列 ,那么我们称字符串 t
是字符串 s
的同位异构字符串。
- 比方说,
"acb dfe"
是"abc def"
的同位异构字符串,但是"def cab"
和"adc bef"
不是。
请你返回 s
的同位异构字符串的数目,由于答案可能很大,请你将它对 109 + 7
取余 后返回。
示例 1:
输入:s = "too hot" |
示例 2:
输入:s = "aa" |
提示:
1 <= s.length <= 105
s
只包含小写英文字母和空格' '
。- 相邻单词之间由单个空格隔开。
地址
https://leetcode.cn/contest/biweekly-contest-94/problems/count-anagrams/
题意
模板题目 + 排列组合
思路
- 题目一看非常简单,无法比较麻烦的是求阶乘的逆元。首先求出每个单词异构的单词的数目,这个很容易求出,我们可以利用排列组合公式,$cnt_i = \dfrac{(a+b+c+\cdots)!}{a!\times b!\times c!\cdots}$,求出每个单词的异构单词数目,然后相乘即可求出整个句子的异构数目,此时需要复杂的操作时需要用到求阶乘的逆元,常规做法利用逆元的求解公式加上快速幂 $a^{-1} \equiv a^{m-2} \pmod m$,当然我们也可以用利用公式在线性时间复杂度内求出阶乘的逆元,这个直接抄模板即可。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示字符串的长度。
- 空间复杂度:$O(n)$,其中 $n$ 表示字符串的长度。
代码
const int MOD = 1e9 + 7; |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://whistle-wind.com/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章