Back to VNotes

Algorithms / LeetCode

算法刷题模型整理(二)

按链表、数组、哈希表、字符串等主题整理常见题型、核心思路和易错点。

LC027 移除元素

解题模型:

​ 双指针

核心思路:

  1. 头尾指针,left命中就把right的值复制到left,然后right左移,left未命中则右移,加起来只用遍历一遍数组,但是会打乱顺序
  2. 快慢指针,left和right同时从0出发,检查right是否命中,未命中则复制到left,然后后移left和right,命中则只后移right,能保持顺序,但有可能遍历两遍数组

易错点:

  • 边界条件
  • 无需交换,可以直接把后面要保留的值复制到前面

LC977 有序数组的平方

解题模型:

​ 双指针

核心思路:

​ 头尾指针,比较left和right的绝对值,大的一个平方过后逆序放入答案数组

易错点:

  • 题目概念,非递减——非严格递增,每一项都>=前面一项
  • 注意逆序放入答案数组
  • 数据特征是对称的,即平方后两边大中间小,所以可以考虑头尾指针

LC209 长度最小的子数组

解题模型:

​ 滑动窗口

核心思路:

​ 用left和right维护一个窗口,同时从下标0出发,

​ 右移right直到符合要求,更新最小长度,然后left后移直到不符合,

​ 一直重复这个过程直到right到达尾部

易错点:

  • 滑动窗口的理解

LC015 三数之和

解题模型:

​ 排序,双指针

核心思路:

​ 降维:3sum->2sum

​ 先排序,固定一个数first,然后简化为两数之和,目标为-first,期间重复的要跳过,因为排序了,所以重复的都是连在一起的,两数之和直接头尾指针,固定left,左移right直到不再大于目标数,等于就添加到答案,小于就右移left,left和right遇到重复的也要跳过,直到left和right相遇,再改变first,重复

易错点:

  • 三处剪枝,1、first不会大于零 2、first和它后面跟着的两个数加起来不会大于0 3、first和最后两个数加起来不会小于0
  • 跳过重复的数时只需要比较它和前面一个数是否相等

哈希表

常见问题:

  1. 数组、unordered_map、map的使用时机
  2. key的范围小且固定或者是整数、字符时用数组
  3. 以上条件不符合时,即key范围较大或key比较复杂时用unordered_map
  4. 若需要元素有序(map特性元素有序存放),范围查找,需要最小、最大则使用map

LC242 有效的字母异位词

解题模型:

​ 字符统计

核心思路:

​ 思路1:先确定长度是否相等,然后哈希表储存每个字符的出现次数,再遍历新串,将遍历到的字符对应出现次数减去1

​ 思路2:对字符串进行排序,若相等则证明是异位词

易错点:

  • 开始先检查长度是否相等,若不相等可以直接结束,并且后续无需再检查哈希表是否全部置零,即新串为子串这种情况,因为长度相等,结束时若有一个字符大于零,必有一个小于零
  • 这题应该使用数组,因为key的范围小,是字符,这题的进阶为会出现unicode字符,这时就要用unordered_map

LC349 两个数组的交集

解题模型:

​ 去重、存在性判断

核心思路:

​ 思路1:哈希表存数组1每个元素出现情况,然后再遍历数组2,元素出现过的存入答案数组

​ 思路2:将两个数组进行排序,双指针分别指向两个数组的开始位置,同时移动,相等则加入答案数组

易错点:

  • 这题使用数组,范围固定,注意的是数组开辟的大小应该是最大元素的值+1,因为元素会作为下标使用
  • 注意去重,元素放入答案数组后要把哈希表中对应的出现情况置0,否则数组2再次出现相同元素时会重复放入答案数组

LC001 两数之和

解题模型:

​ 哈希表/双指针

核心思路:

​ 思路1:建立哈希表存放值与下标,遍历数组,查找值为目标值-当前值的元素,注意先查再存,这样可以防止重复使用,即在查找时,元素自身还没被存放进表中

​ 思路2:先对元素进行从小到大的排序,头尾指针查找答案,若偏小则右移left,偏大则左移right

易错点:

  • 注意不要重复用到元素自身