leetcode biweekly contes 105
比较蛋疼的题目,各种 corn case
太恶心了,t3
竟然给了那么少的数目,太想吐槽了。
6395. 购买两块巧克力
给你一个整数数组 prices
,它表示一个商店里若干巧克力的价格。同时给你一个整数 money
,表示你一开始拥有的钱数。
你必须购买 恰好 两块巧克力,而且剩余的钱数必须是 非负数 。同时你想最小化购买两块巧克力的总花费。
请你返回在购买两块巧克力后,最多能剩下多少钱。如果购买任意两块巧克力都超过了你拥有的钱,请你返回 money
。注意剩余钱数必须是非负数。
示例 1:
输入:prices = [1,2,2], money = 3 |
示例 2:
输入:prices = [3,2,3], money = 3 |
提示:
2 <= prices.length <= 50
1 <= prices[i] <= 100
1 <= money <= 100
地址
https://leetcode.cn/contest/biweekly-contest-105/problems/buy-two-chocolates/
题意
排序
思路
- 直接取最小的两个值即可,比较最小两个值之和与
money
的之间的关系即可 - 复杂度分析:
- 时间复杂度:$O(n \log n)$,$n$ 表示数组的长度。
- 空间复杂度:$O(\log n)$, $n$ 表示数组的长度。
代码
class Solution { |
6394. 字符串中的额外字符
给你一个下标从 0 开始的字符串 s
和一个单词字典 dictionary
。你需要将 s
分割成若干个 互不重叠 的子字符串,每个子字符串都在 dictionary
中出现过。s
中可能会有一些 额外的字符 不在任何子字符串中。
请你采取最优策略分割 s
,使剩下的字符 最少 。
示例 1:
输入:s = "leetscode", dictionary = ["leet","code","leetcode"] |
示例 2:
输入:s = "sayhelloworld", dictionary = ["hello","world"] |
提示:
1 <= s.length <= 50
1 <= dictionary.length <= 50
1 <= dictionary[i].length <= 50
dictionary[i]
和s
只包含小写英文字母。dictionary
中的单词互不相同。
地址
https://leetcode.cn/contest/weekly-contest-346/problems/lexicographically-smallest-palindrome/
题意
动态规划
思路
- 简单题目即可,设 $dp[i]$ 表示前 $i$ 个字符进行有效分割后剩余的最少字符数目,此时可以得到如下递推公式:
- 如果当前的子串 $s[j\cdots i]$ 可以被分割,此时可以知道 $dp[i] = \min(dp[i], dp[j - 1])$;
- 如果当前不存在任何的以 $i$ 为结尾的子串进行分割,此时 $s[i]$ 肯定被剩下,可以得到 $dp[i] = dp[i - 1] + 1$;
- 依次按照上述的递推关系进行检测,即可得到整个字符串剩余的字符的最小值;
- 复杂度分析:
- 时间复杂度:$O(n^2 \times m)$,其中 $n$ 为字符串 $s$ 的长度, $m$ 表示给定字典的最大长度。
- 空间复杂度:$O(Cm)$。
代码
class Solution { |
6393. 一个小组的最大实力值
给你一个下标从 0 开始的整数数组 nums
,它表示一个班级中所有学生在一次考试中的成绩。老师想选出一部分同学组成一个 非空 小组,且这个小组的 实力值 最大,如果这个小组里的学生下标为 i0
, i1
, i2
, … , ik
,那么这个小组的实力值定义为 nums[i0] * nums[i1] * nums[i2] * ... * nums[ik]
。
请你返回老师创建的小组能得到的最大实力值为多少。
示例 1:
输入:nums = [3,-1,-5,2,5,-9] |
示例 2:
输入:nums = [-4,-5,-4] |
提示:
1 <= nums.length <= 13
-9 <= nums[i] <= 9
地址
https://leetcode.cn/contest/biweekly-contest-105/problems/maximum-strength-of-a-group/
题意
贪心
思路
- 题目给的数据太少了,直接暴力完全可以搞定,也可以用贪心解法来面对;
- 所有的整数全部取,负数只取偶数个最小的负数;
- 如果全部为 $0$ 或者 只有一个负数其余全部为 $0$,则直接返回 $0$;
- 如果只有一个数且为负数,则只能返回该负数;
- 复杂度分析:
- 时间复杂度:$O(n \log n)$,其中 $n$ 为数组的长度, 实际时间复杂度可以优化到 $n$;
- 空间复杂度:$O(n)$,其中 $n$ 为数组的长度;
代码
class Solution { |
6464. 最大公约数遍历
给你一个下标从 0 开始的整数数组 nums
,你可以在一些下标之间遍历。对于两个下标 i
和 j
(i != j
),当且仅当 gcd(nums[i], nums[j]) > 1
时,我们可以在两个下标之间通行,其中 gcd
是两个数的 最大公约数 。
你需要判断 nums
数组中 任意 两个满足 i < j
的下标 i
和 j
,是否存在若干次通行可以从 i
遍历到 j
。
如果任意满足条件的下标对都可以遍历,那么返回 true
,否则返回 false
。
示例 1:
输入:nums = [2,3,6] |
示例 2:
输入:nums = [3,9,5] |
示例 3:
输入:nums = [4,3,12,8] |
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 105
地址
https://leetcode.cn/contest/weekly-contest-346/problems/modify-graph-edge-weights/
题意
并查集
思路
- 拿到这个题目第一想到的就是并查集,即如果两个数 $nums[i], nums[j]$ 满足 $\gcd(nums[i],nums[j]) > 1$ 时,此时可以将 $i,j$ 看成存在一条边连接,我们可以采用欧拉素数筛查的办法,如果两个数存在相同的质因子则我们将其进行合并;
- 模仿欧拉线性筛选质数的方法,每次筛选时,将数组中含有相同质因子的数进行合并即可;
- 最终我们检测是否数组中所有的元素都在一个集合中;
- 比较坑的是最后一个
case
, 竟然出现了单个数 $[1]$ 也算是连通,想了好久才过了这个case
;
- 复杂度分析:
- 时间复杂度:$O((U + n)\alpha(n))$,其中 $n$ 为给定的数组的长度,$U$ 表示数组中的最大值;
- 空间复杂度:$O(U)$,其中 $U$ 为给定的数组中的最大值;
代码
class UnionFind { |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://whistle-wind.com/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章