力扣每日一题 2021/6

2021-06-01
6/1 你能在你最喜欢的那天吃到你最喜欢的糖果吗?

难度 MEDI

嘿嘿,儿童节特典,又是那种题目不难但是需要花时间慢慢写的题,关键点在于判断能否吃到的上界和下界,然后用前缀和就可以做了。

6/2 连续的子数组和

难度 MEDI

想了想,对于前缀和,如果sum1 % k == sum2 % k,即sum1 = n1*k + c, sum2 = n2*k + c,那么sum1-sum2这段数组就可以被k整除,然后就是前缀和+哈希表。

6/3 连续数组

难度 MEDI

依然是前缀和+哈希表,两个前缀和分别统计1和0出现的个数,第三个记录sum1[i] - sum0[i]出现的位置,因为要求的其实就是sum1[i] - sum1[j] = sum0[i] - sum0[j]这种情况,变形成sum1[i] + sum0[i] = sum1[j] - sum0[j] + 2 * sum0[i] ,等式左边是当前遍历位置,等式右边,前两个通过查哈希表获得,后一个从前缀和获得。

6/4 相交链表

难度 EASY

我的空间复杂度O(1)的方法是先遍历获得链表长度,再双指针。因为一旦相交后面的就都一样。题解的方法很有技巧性,值得看看。

6/5 移除链表元素

难度 EASY

简单题,不说了。

6/6 一和零

难度 MEDI

因为太久没有做过背包问题导致刚开始不会做。。于是就看了题解。dp有三维,dp[i][j][k]意为选取前i个字符串,有j个0,k个1的最大子集大小,那么,如果当前字符串i可以选择(j >= zero && k >= one),则看看选择后会不会更优,否则就不选当前字符串。总的来说是比较经典的背包问题。

6/7 目标和

难度 MEDI

背包问题的另一种形式,求的不是最优,而是达成某目标的方案数。这一题如果考虑正负就很麻烦,我一开始也是这么写的,题解基于简单的运算:数组和记为sum,目标和target,假设有部分需要取负,记取负的这些数和为f,那么(sum - f) - f = target,即2f == sum - target,右侧已知。当无法满足条件(sum-target小于0或奇数)则直接返回0,否则,原问题转换为:整数数组中找部分数,其和为f的方案数,就是经典的背包问题了。dp二维,dp[i][j]意为选取前i个数,和为[j]的方案数。

6/8 最后一块石头的重量 II

难度 MEDI

划分为两堆石头,相减和即为最终粉碎结果,这个和越小越好,介于0到sum/2。故可以转换为背包问题,dp有两维,dp[i][j]意为可否选前i个石头,其能凑出重量j的石块。第二维从0到sum/2(凑出sum/2则达到了最优解)。最终在最后一列从后往前找对于这个石堆的最优解即可。

6/9 盈利计划

难度 HARD

一开始我用了这样的三维dp,dp[i][j][k]意为选取前i个工作,产生了利润j,员工数用了k的方案数,但是这样写会有问题:按照背包问题的逻辑,当且仅当k >= group[i]且j >= profit[i]时,dp[i][j][k]才能加上dp[i-1][j-pf][k-gp],但是实际上,j < profit[i]时也可以选当前这个工作(之前的可以利润为0),只要选了这个工作后达到最低要求即可,那么可以考虑第二维为产生了最低利润j,这样第二维的空间就从0到sum_profit压缩到0到minProfit。

6/10 零钱兑换 II

难度 MEDI

经典题了,枚举使用前i种面额,每个面额从1到amount凑。。

6/11 完全平方数

难度 MEDI

用了比较常规的解法,从1到n枚举i,记j为sqrt(i),然后j循环到0依次执行$dp[i] = min(dp[i-j*j]+1, dp[i])$,初始化dp[i]为无穷

题解介绍了一种以前学过的“四平方和定理”,即任意一个正整数都可以被表示为至多四个正整数的平方和,特别的, $n = 4^k \times (8m+7)$ 时,n只能被表示为四个正整数的平方和。可以利用这个定理简单处理:若为1,n为平方数;若为2,n为两个平方数之和;若为4,n满足特殊情况;否则为3。

另外还看到一个思路不错的BFS算法,贴个链接

6/12 数位成本和为目标值的最大数字

难度 HARD

虽然是困难但其实不算难,可能是之前背包做多了吧。开二维dp,维度为cost(实际上是常数)和target,然后常规dp即可。

6/13 第一个错误的版本

难度 EASY

二分,爬。不过学到一种防止mid计算过程中超限的方法:$ mid = left + (right - left) / 2$

6/14 猜数字大小

难度 EASY

二分,爬。

6/15 山脉数组的峰顶索引

难度 EASY

二分,爬。

6/16 石子游戏

难度 MEDI

辛辛苦苦dp,结果发现还是博弈论。。

dp的思路很简单,枚举数组大小(2,4,6,8,……),然后三种情况的子数组(AB都选左、右、一左一右),这里只考虑A的最优解,实际上可以考虑B的把情况缩到一种。

但是题解用了博弈论,思路很简单,A始终可以保证自己只选奇数组/偶数组,那么他就可以计算一下哪个大然后只选这个。A要的不是自己选的石头最多,而是石头比B多。因此可以直接返回true。

背包问题小结

背包问题总的来说可以分为三种:1是求最佳方案;2是求能否取子集,和为目标数(达成目标方案);3是求和为目标数的子集的总数。2和3做法基本一致,只不过前者统计true还是false,后者统计个数。

开的dp的第一维是用来枚举背包数组,意为选取前i个的情况。如果有目标数,一般第二维枚举目标数。剩下的维度感觉没有规律,依据题目而定。

6/17 有效数字

难度 HARD

写了正则表达式,可惜C++的超时过不了,改成python过了。题解给的解法是自动机,写的挺烂的。。

6/18 最小好进制

难度 HARD

数学。好难。睡大觉。

6/19 串联字符串的最大长度

难度 MEDI

写着麻烦又不难(数据量小所以可以2的n次方),直接CV了。

6/20 皇位继承顺序

难度 MEDI

直接进行一个哈希表的做。。。

考试周复习,很多题没做。。之后慢慢补

6/2

难度 EASY

6/2

难度 MEDI

6/2

难度 HARD

本文阅读量: