leetcode contest 374
T4
确实是个好题目,总体来说本周周赛题目确实还算比较难,不过前三题难度还好,基本上不需要太多技巧。
2951. 找出峰值
给你一个下标从 0 开始的数组 mountain
。你的任务是找出数组 mountain
中的所有 峰值。
以数组形式返回给定数组中 峰值 的下标,顺序不限 。
注意:
- 峰值 是指一个严格大于其相邻元素的元素。
- 数组的第一个和最后一个元素 不 是峰值。
示例 1:
输入:mountain = [2,4,4] |
示例 2:
输入:mountain = [1,4,3,8,5] |
提示:
3 <= mountain.length <= 100
1 <= mountain[i] <= 100
地址
https://leetcode.cn/contest/weekly-contest-374/problems/find-the-peaks/
题意
模拟
思路
- 直接模拟即可,检测相邻元素的差值即可。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示给定数组的长度。
- 空间复杂度:$O(1)$。
代码
class Solution: |
2952. 需要添加的硬币的最小数量
给你一个下标从 0 开始的整数数组 coins
,表示可用的硬币的面值,以及一个整数 target
。
如果存在某个 coins
的子序列总和为 x
,那么整数 x
就是一个 可取得的金额 。
返回需要添加到数组中的 任意面值 硬币的 最小数量 ,使范围 [1, target]
内的每个整数都属于 可取得的金额 。
数组的 子序列 是通过删除原始数组的一些(可能不删除)元素而形成的新的 非空 数组,删除过程不会改变剩余元素的相对位置。
示例 1:
输入:coins = [1,4,10], target = 19 |
示例 2:
输入:coins = [1,4,10,5,7,19], target = 19 |
示例 3:
输入:coins = [1,1,1], target = 20 |
提示:
1 <= target <= 105
1 <= coins.length <= 105
1 <= coins[i] <= target
地址
https://leetcode.cn/contest/weekly-contest-374/problems/minimum-number-of-coins-to-be-added/
题意
贪心
思路
- 题目带一点技巧,但是也不是很难,首选我们需要对数组按照从小到达进行排序,我们假设前 $i-1$ 个元素组成的数字之和的最大值 $x$, 此时的元素为 $y = coins[i]$,此时可以知道:
- $[1,2,3,4,\cdots,x]$ 都已经全部构成,此时我们知道加入加上 $coins[i]$ 后,此时可以构成 $[y,1 + y, 2 + y, 3 + y, 4 + y, \cdots,x + y]$;
- 如何保证上述两部分数组连续,此时只需要满足 $y \le x + 1$ 即可,此时我们知道可以构成的最大元素即为 $x + y$, 我们更新 $x$ 即可;
- 根据以上推论,我们只需检测到当前数目可以累加到 $target$ 即可。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示给定的数组的长度
- 空间复杂度:$O(1)$,其中 $n$ 表示给定字符串的长度。
代码
class Solution: |
2953. 统计完全子字符串
给你一个字符串 word
和一个整数 k
。
如果 word
的一个子字符串 s
满足以下条件,我们称它是 完全字符串:
s
中每个字符 恰好 出现k
次。- 相邻字符在字母表中的顺序 至多 相差
2
。也就是说,s
中两个相邻字符c1
和c2
,它们在字母表中的位置相差 至多 为2
。
请你返回 word
中 完全 子字符串的数目。
子字符串 指的是一个字符串中一段连续 非空 的字符序列。
示例 1:
输入:word = "igigee", k = 2 |
示例 2:
输入:word = "aaabbbccc", k = 3 |
提示:
1 <= word.length <= 105
word
只包含小写英文字母。1 <= k <= word.length
地址
https://leetcode.cn/contest/weekly-contest-374/problems/count-complete-substrings/
题意
滑动窗口
思路
- 不太明白这个题目也标 $hard$,题目本身不是很难,涉及一个核心问题,$s$ 中每个字符恰好出现 $k$ 次,此时 $s$ 的长度一共有 $26$ 可能,$len(s) \in[k,2k, \cdots, 26k]$,我们枚举 $s$ 的长度 $l$:
- 设以 $i$ 为结尾构成满足相邻字符差距小于等于 $2$ 的长度为 $dp[i]$, 此时 $l \le dp[i]$;
- $s[i-l+1:i]$ 之内的字符串均满足相同字符的数目均为 $k$, 我们可以利用前缀和求出相同字符的数目;
- 时间复杂度:
时间复杂度:$O(n\times |\Sigma|^2)$,其中$n$ 表示给定数组的长度;
空间复杂度:$O(n \times |\Sigma|)$,其中$n$ 表示给定数组的长度;
代码
class Solution { |
2954. 统计感冒序列的数目
给你一个整数 n
和一个下标从 0
开始的整数数组 sick
,数组按 升序 排序。
有 n
位小朋友站成一排,按顺序编号为 0
到 n - 1
。数组 sick
包含一开始得了感冒的小朋友的位置。如果位置为 i 的小朋友得了感冒,他会传染给下标为 i - 1
或者 i + 1
的小朋友,前提 是被传染的小朋友存在且还没有得感冒。每一秒中, 至多一位 还没感冒的小朋友会被传染。
经过有限的秒数后,队列中所有小朋友都会感冒。感冒序列 指的是 所有 一开始没有感冒的小朋友最后得感冒的顺序序列。请你返回所有感冒序列的数目。
由于答案可能很大,请你将答案对 109 + 7
取余后返回。
注意,感冒序列 不 包含一开始就得了感冒的小朋友的下标。
示例 1:
输入:n = 5, sick = [0,4] |
示例 2:
输入:n = 4, sick = [1] |
提示:
2 <= n <= 105
1 <= sick.length <= n - 1
0 <= sick[i] <= n - 1
sick
按升序排列。
地址
https://leetcode.cn/problems/count-the-number-of-infection-sequences/description/
题意
组合数学
思路
- 题目本身还是比较难的,我们首先假设两个感冒的小朋友为 $(x,y)$,他们之间的距离为 $k$ 个位置时,有多少种感冒序列:
此时我们可以知道第一个小朋友可以感染 $[0,1,2,3,4, \cdots, k]$ 个人,同时第二个小朋友可以感染 $[k, k - 1, k - 2, \cdots, 0]$ 个人;
此时假设第一个小朋友感染右边的 $i$, 则右边的小朋友会感染左边的 $k-i$ 个人。此时左边的感染序列是 $[0, 1,2, 3,4,\cdots, i]$, 右边的感染序列是$[0, 1, 2, 3,4, \cdots, n - i]$;我们可以看到产生的序列可能如下:
$$
[1,0,0,\cdots, 0, 0] \
[1,1,0,\cdots, 0, 0] \
[1,1,0,\cdots, 0, 1] \
\cdots \
[1,1,1,\cdots, 1, 1]
$$
上述序列的长度一共是 $k$ 个,我们可以看到无论 $i$ 为何值,此时最后一个序列总是相同的,此时我们只需要在前 $k-1$ 个序列中选择 $i-1$ 个序列分配给第一个小朋友的感染序列,此时第二个小朋友的感染序列即可确定,此时可能的选择方法数目为 $C_{k-1}^{i-1}$,此时我们知道 $i \in [0,k]$个,则此时可以知道总共可能的选择序列数目有 $C_{k-1}^{0} + C_{K-1}^{1} + \cdots + C_{k-1}^{k-1} = 2^{k-1}$个;假设存在现在存在多个感冒序列,长度分别为 $l_0,l_1,l_3 \cdots$,则此时可以选择的方法数目为 $s = C_{l1+l2+l3 + \cdots}$ 中选择 $l_1$ 个位置存在 $l_1$ 的感冒序列,$l_2$ 个位置存在 $l_2$ 的感冒序列,此时总共的方法数目为 $C_s^{l_1} \times C_{s-l_1}^{l2} \times C_{s-l_1-l_2}^{l_3}$;
根据以上分析我们直接模拟即可,由于 $C_M^{N}$ 可能较大,此时需要进行乘法逆元运算,我们可以利用线性的乘法逆元计算即可,直接用快速幂求每个逆元的话会超时。
- 复杂度分析:
- 时间复杂度:$O(n \log U)$,其中 $n$ 表示数组的长度,$U$ 表示数组中元素的最大值;
- 空间复杂度:$O(n)$,其中 $n$ 表示数组的长度;
代码
class Solution: |
class Solution { |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://whistle-wind.com/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章