Array
LC 188
输入: nums = [1,2,3,4,5,6,7], k = 3 输出: [5,6,7,1,2,3,4]
方法一:切片操作;取数组里的后k个元素:nums[-k%n:]
方法二:先反转整体,再反转局部. 反转过程单独实现,不要用切片,因为可能会产生额外空间。
枚举
枚举右,维护左边
1031. 两个无重叠子数组的最大和
写一个函数,求左边的长度为l,右边的长度为r时的最大和
枚举右边的右端点,当右边的窗口每向右移动一步,左边的【可能最大值】也被更新了
双指针
相向双指针
LC 75: Sort Colors
用一个指针i来遍历这个数组,还需要用左右指针来指向下一个0或2待填入的位置。先用循环不断地填充2,然后遇到0的时候,填充0。
循环条件:i<=r。因为当i>r的时候,nums[i]肯定为2
15. 三数之和
双指针,需要注意索引处理.
首先外层指针需去重,内层的两个指针在每次获得答案的时候去重
42. 接雨水
双指针,一定要先更新最大值,再判断往哪边加水。
可以考虑普通的做法,即用两个数组保存从左边/从右边遍历时见过的最大值,这个最大值,是包括x本身的,所以要先更新最大值。
双序列
双序列双指针
88. 合并两个有序数组
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
双指针应当从后往前移动
844. 比较含退格的字符串
结束循环的条件必须是 while i>=0 or j>=0。不然的话,当 i<0, j>=0 的时候,循环就结束了,判断为 False,而j此时或许还在#上。
某个指针或许需要多一次,循环移动,来把这个字符串消耗完。比如"n"和"b#n"
244. 最短单词距离 II
拿两个list出来比较,找到里面最接近的pair.
双指针每次计算距离,然后根据值的大小,选择移动其中一个指针
三指针
2444. 统计定界子数组的数目
- 假设所有元素都在minK, maxK 之间,那么一边遍历 array,一边看是否出现 minK, maxK,以及记录它们的 index。若当遍历到某个数时,minK 和 maxK 都找到了,则以此时的 i 为右端点,左端点在 [0,min(minI, maxI)]的所有subarray 都符合条件
- 但事实上,有些元素不在[minK, maxK]之间,那么需要一个额外的 index 来记录上次越界元素出现的位置。则,minK和 maxK 都需要在 index 右边出现才行。并且左端点需要在[index+1, min(minI, maxI)]之间
技巧
277. 搜寻名人
- 遍历所有人,找到唯一一个可能是candidate的人
- 初始化candidate=0, 枚举第1个到第n-1个候选人。
- 一旦发现knows(candidate, i),则说明此时candidate不可能是名人了,更新candidate为i
- 这一遍遍历结束,也不能说明所有哦人都认识candidate
- 对于该candidate,遍历所有人,确认他是否是真的名人
287. 寻找重复数
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。
如果一个数组中没有重复的数,比如[1,3,4,2]。遍历index:从0到n-1 ,建立index到nums[index]的映射
0->1->3->2->4->null
如果有重复的数,比如[1,3,4,2,2],因为所有元素都在[1, n] 范围内,所以必然存在一个环。为什么答案即环的起点呢?因为存在i,j,使得nums[i]=nums[j]=x,即两个节点会指向同一个节点
0->1->3->2->4->2->4
448. 找到所有数组中消失的数字
用原数组记录哪个数字出现过,想象有另一个长度为n的数组,从1到n,用来记录哪个数组出现过,哪个数字没出现过。
- 比如数字4出现了,此时就把nums[4-1]+=n。
- 如果每个数字都出现了,那么最后的nums应该是所有元素都大于n
945. 使数组唯一的最小增量
排序,然后找到数组中的最大值m,给所有数字做一个count。
从1遍历到m,如果遇到cnt[x]>1, 就把他往后推一位
最后,cnt[m+1]如果>1,把多余的都往后推
置换环
| |
2471. 逐层排序二叉树所需的最少操作数目
比如说排序一个数组,每次操作可以两两交换,希望找到最少需要的操作数量。
array=[2,0,1,4,3]
这里[2,0,1]是一个置换环,[4,3]是一个置换环。
从第一个数开始,把这个数字当成下标去访问数组,不断循环直到回到这个数本身。
我们只需要计算每个环内需要多少次交换。对于每个环,交换次数为环的大小减一。
如果一个数组有N个数字,有M个环,则总共需要的交换次数为N-M
41. 缺失的第一个正数
记得在交换前,一定让index=arr[i]-1
还有循环条件是 while 1<=arr[i]<=n and arr[i]!=arr[arr[i]-1] 因为此时的arr[i]一定是可以对应到一个位置的,把它放到需要的位置上
不可以是arr[i]!=i+1, 因为i+1不一定在这个数组中存在,这会陷入无限循环
哈希表
最大平衡异或子数组的长度
子数组的按位异或(XOR)为 0。
子数组包含的 偶数 和 奇数 数量相等。
N xor M=K, K xor N=M,保持一个记录当前xor的变量,如果想把某个数字N从窗口中移除,直接 xor N即可
所以,可以对xor作前缀和
如何知道一个子数组,它的 偶数 和 奇数 数量相等?
diff用来表示偶数数量-奇数数量,当哈希表记录的前后两次diff相同时,表示这一段子数组的偶数和奇数数量相等
如何知道一个子数组,他的XOR为0?
同样,用hash记录每个index到目前为止的XOR,如果前后两次值一样都为M,则这一段子数组的XOR为0. (M xor 0)=M