leetcode weekly contes 368
本周的题目难度还是非常高的,特别是 T3
是个好题目,容易出错,且不好写的题目。
2908. 元素和最小的山形三元组 I
给你一个下标从 0 开始的整数数组 nums
。
如果下标三元组 (i, j, k)
满足下述全部条件,则认为它是一个 山形三元组 :
i < j < k
nums[i] < nums[j]
且nums[k] < nums[j]
请你找出 nums
中 元素和最小 的山形三元组,并返回其 元素和 。如果不存在满足条件的三元组,返回 -1
。
示例 1:
输入:nums = [8,6,1,5,3] |
示例 2:
输入:nums = [5,4,8,7,10,2] |
示例 3:
输入:nums = [6,5,4,3,4,5] |
提示:
3 <= nums.length <= 50
1 <= nums[i] <= 50
地址
https://leetcode.cn/contest/weekly-contest-368/problems/minimum-sum-of-mountain-triplets-i/
题意
枚举
思路
- 设 $nums[i]$ 为三元组中的中间元素,则此时和最小情形应该是 $[0,i-1]$ 的最小值加上 $[i+1,n-1]$ 的最小值,此时我们利用前后缀分别保存前 $i-1$ 个元素的最小值,以及从 $i+1$ 开始往后的最小值,依次遍历枚举即可。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示给定的数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 表示给定的数组的长度。
代码
class Solution: |
2909. 元素和最小的山形三元组 II
给你一个下标从 0 开始的整数数组 nums
。
如果下标三元组 (i, j, k)
满足下述全部条件,则认为它是一个 山形三元组 :
i < j < k
nums[i] < nums[j]
且nums[k] < nums[j]
请你找出 nums
中 元素和最小 的山形三元组,并返回其 元素和 。如果不存在满足条件的三元组,返回 -1
。
示例 1:
输入:nums = [8,6,1,5,3] |
示例 2:
输入:nums = [5,4,8,7,10,2] |
示例 3:
输入:nums = [6,5,4,3,4,5] |
提示:
3 <= nums.length <= 105
1 <= nums[i] <= 108
地址
https://leetcode.cn/contest/weekly-contest-368/problems/minimum-sum-of-mountain-triplets-ii/
题意
枚举
思路
- 与第一题的解法一模一样,设 $nums[i]$ 为三元组中的中间元素,则此时和最小情形应该是 $[0,i-1]$ 的最小值加上 $[i+1,n-1]$ 的最小值,此时我们利用前后缀分别保存前 $i-1$ 个元素的最小值,以及从 $i+1$ 开始往后的最小值,依次遍历枚举即可。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示给定的数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 表示给定的数组的长度。
代码
class Solution: |
2910. 合法分组的最少组数
给你一个长度为 n
下标从 0 开始的整数数组 nums
。
我们想将下标进行分组,使得 [0, n - 1]
内所有下标 i
都 恰好 被分到其中一组。
如果以下条件成立,我们说这个分组方案是合法的:
- 对于每个组
g
,同一组内所有下标在nums
中对应的数值都相等。 - 对于任意两个组
g1
和g2
,两个组中 下标数量 的 差值不超过1
。
请你返回一个整数,表示得到一个合法分组方案的 最少 组数。
示例 1:
输入:nums = [3,2,3,2,3] |
示例 2:
输入:nums = [10,10,10,3,1,1] |
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 109
地址
题意
枚举
思路
- 设当前分组的下标数量的最大值为 $x$,刚开始拿到题目准备用二分查找,后来仔细发现实际并不满足单调性,无法使用二分查找,比如 $[1,1,1,1,1]$ 利用二分查找时可能会失效,$x=3$ 的时候成立,$x=4$ 的时候不成立,$x=5$ 时成立,则不符合单调性,因此不能用二分查找问题。由于每个分组只能为相同的元素,首先我们对各个元素进行分组统计,假设我们已经知道当前所有分组中下标数量最多的数目为 $x$,则此时所有分组中下标的数量要么是 $x$,要么是 $x-1$,此时我们即可计算出分数的数量。本题本质上就是求最大的分组的下标数量 $x$。仔细分析一下:
- $x$ 的取值范围,假设当前相同元素中,出现次数最少的数字为 $k$,出现次数为 $cnt[k]$, 则此时 $x$ 的取值一定不能大于 $cnt[k] + 1$,否则无法成立,因此我们可以知道 $x$ 的取值范围为 $[1,cnt[k] + 1]$;
- 根据上面推论,我们找到 $x$ 的取值范围后,依次枚举 $x$,找到最大的 $x$ 可以满足分组要求则返回当前的分组个数即可;
- 假设当前数字的数量为 $v$ 个,我们如何将其划分为大小为 $x,x-1$ 的分组,$v$ 到底需要满足什么条件才可以划分?
- $v \mod x = 0$ 时,此时我们直接划分,因为此时可以将 $v$ 划分为 $\dfrac{v}{x}$ 个分组;
- $v \bmod x \neq 0$ 时,此时我们无法直接划分,需要进行检测:
- 我们可以知道此时有 $t = \lfloor \dfrac{v}{x}\rfloor$ 个 $x$,剩余的元素为 $v \mod x$ 个,此时我们需要将 $v \bmod x$ 尽量往 $x- 1$ 上凑,至少还需要 $x-1 - v \bmod x$ 个元素才能凑成 $x-1$,。此时由于存在 $t$ 个 $x$ ,每个 $x$ 最多可以取出一个 $1$,一共可以取出 $t$ 个 $1$,此时只需要满足 $t \ge (x - 1) - v \bmod x$, 即此时需要满足 $t + 1 \ge x - v \bmod x$ 即可满足上述要求。
- 根据上述分析,我们直接枚举窗口大小并进行模拟即可。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中$n$ 表示数组的长度;
- 空间复杂度:$O(n)$,其中$n$ 表示数组的长度;
代码
class Solution: |
2911. 得到 K 个半回文串的最少修改次数
给你一个字符串 s
和一个整数 k
,请你将 s
分成 k
个 子字符串 ,使得每个 子字符串 变成 半回文串 需要修改的字符数目最少。
请你返回一个整数,表示需要修改的 最少 字符数目。
注意:
- 如果一个字符串从左往右和从右往左读是一样的,那么它是一个 回文串 。
- 如果长度为
len
的字符串存在一个满足1 <= d < len
的正整数d
,len % d == 0
成立且所有对d
做除法余数相同的下标对应的字符连起来得到的字符串都是 回文串 ,那么我们说这个字符串是 半回文串 。比方说"aa"
,"aba"
,"adbgad"
和"abab"
都是 半回文串 ,而"a"
,"ab"
和"abca"
不是。 - 子字符串 指的是一个字符串中一段连续的字符序列。
示例 1:
输入:s = "abcac", k = 2 |
示例 2:
输入:s = "abcdef", k = 2 |
示例 3:
输入:s = "aabbaa", k = 3 |
提示:
2 <= s.length <= 200
1 <= k <= s.length / 2
s
只包含小写英文字母。
地址
https://leetcode.cn/contest/weekly-contest-368/problems/minimum-changes-to-make-k-semi-palindromes/
题意
动态规划
思路
其实感觉
T4
过于套路的题目了,感觉没啥太大的难度,设 $dp[i][j]$ 表示将前 $i$ 个字符转换为 $j$ 个半回文串的最少修改次数,次数可以可以得到递推公式为:
$$
dp[i][j] = \min(dp[i][j], dp[i-m][j-1] + cost[i-m+1][i])
$$
其中 $cost[i-m+1][i]$ 表示将字符串 $s[i-m+1\cdots i]$ 转化为半回文串的最少替换次数,这个求法比较简单,我们直接计算即可,不需要太花费时间,我们依次尝试对于子串 $s[i-m+1\cdots i]$ 尝试所有可能的 $d$,此时 $d\in[1,m-1]$,依次求出所有可能的划分即可,可以提前预处理,求出所有的 $cost[i][j]$,本身难度不是很大,没有太多需要描述。复杂度分析:
- 时间复杂度:$O(n^3 \log n + k\times n^2)$,其中 $n$ 表示字符串的长度,$k$ 为给定的元素;
- 空间复杂度:$O(n^2)$,其中 $n$ 表示字符串的长度;
代码
class Solution: |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://whistle-wind.com/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章