根据数据结构,可以将算法题分成数组、字符串、链表、栈、队列、树等几大类。根据算法,可以将题分为递归和循环、查找和排序、回溯法、动态规划和贪婪算法、位运算、DFS&BFS、随机、数学等几大类。而算法和数据结构又是一个排列组合的过程。
上面介绍的算法和数据结构都是要十分熟练的掌握的,就不再总结,下面我们总结的是一些常见的技巧,有了这些技巧伴身,相信秋招算法题不在话下。
这种类型的题通常结合数组和链表这两种数据结构,窗口大小可能是固定的也可能是变化的。
题目关键词:
经典题目:滑动窗口四题小结
同向双指针和异向双指针。
通常用于解决排好序的数组或者链表中寻找对子。比如比较数组中每个元素和其他元素的关系。
【使用双指针为了将时间复杂度从O(n2)降低到O(n)】
识别关键词:
通常用于解决有环的链表和数组。
识别关键词:
环形链表,环形数组
需要知道链表长度或者某个特别位置的信息
双指针和快慢指针区分:
单链表不能用双指针,判断链表是否回文需要用快慢指针来找到中间元素。
处理有区间重叠的高效技术,一共分为六种情况。
识别关键词:
用来处理数组中数值限定在一定区间的问题。
方法:遍历数组中的元素,如果当前数不在它应该在的位置上,就交换与应该在的位置上的那个数。
识别关键词:
适用于翻转链表中的某一段节点,原地翻转。
方法:每次翻转一个节点,需要current、previous两个变量,previous总是指向刚处理完的节点。
识别关键词:
适用于需要遍历一棵树且需要一层层的遍历的问题。
借助于队列把根节点加入到队列中,不断遍历,直到队列为空,每次循环把头结点拿出来做一些操作,删除的时候将其孩子节点加入到队列中。
识别关键词:
适用于深搜实现树的遍历。
方法:使用递归或者迭代栈的方式。从根节点开始,如果该结点不是叶子节点,需要区别我们是先处理根节点,处理孩子节点之间处理根节点,还是处理完所有孩子再处理根节点(分别对应于前中后序),然后递归处理当前节点的左右孩子。
识别关键词:
适用于包含可以分为两队的数字。将数字分成两半,小的放在一起,大的放在另一半。
方法:
一个最小堆用来寻找最小元素,一个最大堆拿到最大元素。可以使用O(1)的时间找到两边的最大或最小元素。从两个堆顶找到数字,从而计算出中位数。
识别关键词:
适用于排列组合问题
方法:使用BFS来处理这些问题。
识别关键词:
适用于输入是拍好序的数组、链表或者矩阵,要我们寻找某些特定元素。
方法:对于一组满足上升排列的数集来说,步骤如下:
识别关键词:
适用于让我们求解最大/最小/最频繁的K个元素的题。
方法:堆。Java中叫优先队列,PriorityQueue。
识别关键词:
适用于涉及到多组排好序的数组的问题。
方法:输入是K个排好序的数组,将每个数组的最小元素加入到最小堆,从而得到全局最小值,再从该元素所在的数组里取出其后面紧挨着的元素,加入堆。直到处理完所有元素。
识别关键词:
见下面第二部分“动态规划”
适用于寻找一种线性的顺序,元素之间具有依赖性。比如,事件B依赖于事件A,A在拓扑排序顺序中排在B的前面。
方法:1)初始化;2)创建图,计算每个节点的入度;3)找所有的起点;4)排序。
识别关键词:
Leetcode0-1背包小结(Python)
Leetcode完全/无限背包小结(Python)
最长公共子序列
【题目地址】
#闫氏DP分析法,链接地址 https://www.acwing.com/video/946/
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
#状态表示:集合:考虑text1的前i个字符和text2的前j个字符,两者中的公共子串 属性:最大
#状态计算:00 01 10 11 f(i-1, j-1) f(i-1, j) f(i, j-1) f(i-1, j-1)+1
dp = [[0 for i in range(len(text2)+1)] for j in range(len(text1)+1)]
for i in range(1, len(text1)+1):
for j in range(1, len(text2)+1):
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
if text1[i-1] == text2[j-1]:dp[i][j] = max(dp[i-1][j-1]+1, dp[i-1][j-1])
return dp[-1][-1]