力扣每日一题 2021/5

2021-05-01
5/1 员工的重要性

难度 EASY 链接

劳动节让大家认识到员工的重要性XDDDDD

题目挺简单的,dfs就行,为了方便查找用了哈希表。

5/2 砖墙

难度 MEDI 链接

理解难度远大于做题难度。。。想法就是找空隙最多的,也就是每行统计一下累加和作为当前间隙的坐标。

一开始用了普通的数组但是超时了,改为哈希表就行。

5/3 整数反转

难度 EASY 链接

难道是因为放假所以题目都很简单?

没啥好说的,善用to_string和atoi即可。

5/4 粉刷房子 III

难度 HARD 链接

打脸了打脸了打脸了好难好难好难

属于是CV工程师了。。思路依然是dp,但是是三维的,$dp[i][j][k]$表示0到i都涂完色,第i个房子颜色为j,并且属于第k个街区时的最小花费。。

5/5 删除并获得点数

难度 MEDI 链接

用了一个map,然后动态规划的时候考虑能不能find到当前元素-1的值就行。答案的做法是分成子数组,子数组内任意相邻元素之差不超过 1。

5/6 解码异或后的数组

难度 EASY 链接

简单题。。

5/7 数组异或操作

难度 EASY 链接

学习到了一个做题有点用的公式:$\forall i \in Z,有 4i \oplus (4i+1) \oplus (4i+2) \oplus (4i+3) = 0$

题目本身是那种技巧性很强的题。。

5/8 完成所有工作的最短时间

难度 HARD 链接

好难好难好难。贴一个题解,其中提到的暴力dfs+剪枝的套路很值得学习,至于官方的解法虽然效果很好,但非常复杂。。

5/9 制作 m 束花所需的最少天数

难度 MEDI 链接

每次检查当前天数下能否满足只要遍历一次数组即可,而总的找最小天数则可以使用二分查找。

5/10 叶子相似的树

难度 EASY 链接

dfs即可。

5/11 解码异或后的排列

难度 MEDI 链接

又是异或。。用了上次学到的sumXor进行快速处理求得x1\^x2…\^xn,再通过encoded本身运算求得x2…\^xn,二者处理得到x1,之后顺势推出其余数字。

5/12 子数组异或查询

难度 MEDI 链接

又是异或。。。和昨天的类似,利用x1\^x2^x2 = x1这样的原理进行运算。

5/13 停在原地的方案数

难度 HARD 链接

题目难在dp数组二维用哪个。。没想到看了题解,然后自己做的过程就比较简单了。dp[i][j]表示走了i步,到达j的方案数。i的取值范围从0到steps,j的从0到min(arrLen-1,steps),即只能到尽头,不能走更远。

5/14 整数转罗马数字

难度 MEDI 链接

简单题,多分情况就行。

5/15 罗马数字转整数

难度 EASY 链接

。。。昨天的姊妹篇。。。

5/16 数组中两个数的最大异或值

难度 MEDI 链接

没有想到O(n)的方法。看了题解是用了字典树存所有的数字(所有数字都只用了31位),然后对每个值贪心地求其最大的异或结果,方法为:从高到低,已有当前指针(即当前位前面的都已确定)若当前位为1,找0,没有再找1;若当前位为0则找1,没有再找0,这样就在O(1)时间找到了当前数字对应的最大异或结果的那个值。。

5/17 二叉树的堂兄弟节点

难度 EASY 链接

dfs就行。。

5/18 形成两个异或相等数组的三元组数目

难度 MEDI 链接

核心思想就是,当从i到k的一段数组异或和为0时,怎么分割都能满足题意。但是我用了朴素的O(n^2)的方法。题解提供了利用哈希表达成O(n)的算法,因为“从i到k的一段数组异或和为0”可以转换为前缀异或和S[i-1] == S[k],用哈希表可以记录所有相同前缀和,从而达到一次遍历就得到答案。

5/19 找出第 K 大的异或坐标值

难度 MEDI 链接

异或和已经做烂了。。。这题让我发现了C++的STL居然有内置的快速选择函数:

#include <algorithm>
//排序规则采用默认的升序排序
void nth_element (RandomAccessIterator first,
                  RandomAccessIterator nth,
                  RandomAccessIterator last);
//排序规则为自定义的 comp 排序规则
void nth_element (RandomAccessIterator first,
                  RandomAccessIterator nth,
                  RandomAccessIterator last,
                  Compare comp);

查找第nth大的元素并放在nth的位置。似乎还用了随机数来规避最坏情况O(n)。好用。

5/20 前K个高频单词

难度 MEDI 链接

《STL大挑战》。。题目不难,哈希表统计词频,再存到最大堆里,再pop k次。中间还用到了操作符重载。不过我做完了仔细一想这复杂度不是nlogk还是nlogn啊,但是建立大小为k的最大堆比较麻烦,看了题解用了优先队列,并且用了很多c++11的新特性,比如构造时第三个参数,比较函数的类型,使用了delctype(exp),这个关键字会得到exp的类型,非常好用。

5/21 不相交的线

难度 MEDI 链接

想了半天想出来一个这样的动态规划:

$x=nums1[i],\ y=nums2[i],\ dp[i] = max(dp[i-1],dp[nums2.x-1]+1, dp[nums1.y-1]+1)$

$dp[i] = max(dp[i-1]+1, dp[i])\ if\ x==y$

其中nums2.X表示上次出现x的位置

然而这个会有很大的问题,例如[2,3,1,13,14,15]和[8,9,10,2,3,1],当移动到nums2的3时,此时dp[0]为0,所以我就在想应该需要二维数组来做。。

然后看了题解恍然大悟。。。这就是最长公共子序列。。。换了个方式就看不出来了。。

5/22 黑板异或游戏

难度 HARD 链接

看到必胜策略就先推导了一下,结果发现偶数的必胜???吓得我看了题解发现还真是这样。。。那就很简单了,初始偶数A赢,否则初始异或和为0时A赢,剩下就是输。。

5/23 与数组中元素的最大异或值

难度 HARD 链接

利用了5/16的方法,先对NUMS排序,再二分法查到比查询值mi小(或相等)的最大值,假设字典树向右为1,用这个节点走一遍字典树,如果向左且向右不为空,把向右的ban掉(用符号位表示,同时加入一个数组暂存,数组大小不超过30),再对当前字典树用5/16的方法找到与xi异或最大的,再把ban掉的恢复(利用数组)。

时间复杂度为O(nlogn + mlogn),n为NUMS大小,m为QUERIES大小。

5/24 奇怪的打印机

难度 HARD 链接

又是困难。。是不会做的动态规划,直接看题解吧。。

不过在宫水三叶的题解里看到一句有用的做题家教程:数据是10\^2的,即题解在O(n\^3),又因为应该要用dp,就可以推断出应该是「枚举长度 + 枚举另一边端点 + 枚举分割点」的三重循环。

5/25 使所有区间的异或结果为零

难度 HARD 链接

怎么又是困难啊啊啊啊。这回题解都看不懂了,直接CV睡大觉。

5/26 反转每对括号间的子串

难度 MEDI 链接

题目难度适中,认真做即可。

5/27 汉明距离

难度 EASY 链接

逐位统计即可。

5/28 汉明距离总和

难度 MEDI 链接

这道题挺有意思的,死活没有想到怎么能在O(n)完成,题解的解释是,在统计某一位的汉明距离和时,不需要考虑其他位的情况,故可以O(n*L)完成,L是int长度。具体的逻辑是对于每一位,统计所有的(val » i) & 1之和,即1的个数,记为c,则c*(n-c)即为这一位的汉明距离和(每一个1和其他所有0距离为1)。

5/29 元素和为目标值的子矩阵数量

难度 HARD 链接

通过固定上下转换成数组的形式,而数组可以用前缀和+哈希表求值。。一看题解就是会做题,但是自己想还是不太好想。。下次记得矩阵可以加时间转数组。。

5/30 2 的幂

难度 EASY 链接

简单题,利用之前学到的n&(n-1)是去掉最后一个1来做。如果是2的幂那么去掉最后一个1就是0,反之亦然,

5/314的幂

难度 EASY 链接

一开始铸币了想着直接右移做。。但是这样只能排除2,利用昨天的,4的幂的特点除了只有1个1,还有这个1在偶数位上,那么就用mask来加一个判断即可。

本文阅读量: