算法Tips大总结

Two Pointers:

针对双指针滑动窗口的经典写法: 右指针不断往右边移,移动到不能往右边继续移动为止(究竟什么是不能动了 就根据具体的题目来定)当右指针到最右边以后 开始挪动左指针 释放窗口左边界。(经典题目:第 3 题,第 76 题,第 209 题,第 424 题,第 438 题,第 567 题,第 713 题,第 763 题,第 845 题,第 881 题,第 904 题,第 978 题,第 992 题,第 1004 题,第 1040 题,第 1052 题。特别经典的题目:第 239 题,第 480 题。)
快慢双指针可以查找重复。
双向双指针或者多指针可以解决N sum问题。

LinkedList:

注意dummy node的使用。只要是头部节点有可能出现变动 我们是一定需要dummy node的。
大体上 链表的题型,无非是:区间逆序,找中间节点或者正数或者是倒数第K隔节点。K路归并节点,链表排序(这里说的排序是指把一个链表的内部节点进行排序,而解决的方法只有一种方式:归并排序),判断是否有环以及环的起点在哪里。

Stack:

常见的问题:
括号匹配问题以及类似问题。
栈的基本pop和push操作
利用栈进行编码的问题 LC394 LC682 LC856 LC880
需要利用单调栈来解的问题(就是说利用栈维护一个单调递增或者递减的下标数组)

Backtracking

排列问题
组合问题
排列组合杂交问题:LC1079
数独问题
四个方向搜索(flood fill)
subset
trie
BFS优化(因为BFS本质上是complete search 而backtracking实际上是剪枝的,也就是优化版本的BFS/DFS)

Binary Search

参见本博主的:模板题目:Binary Search (35. Search Insert Position)
注意其他的可以用二分搜索的题目:比如那些基本有序的数组:在山峰数组中找山峰,在旋转有序数组中找分界点。第 33 题,第 81 题,第 153 题,第 154 题,第 162 题,第 852 题。
max-min 最大值最小化问题。求在最小满足条件的情况下的最大值。第 410 题,第 875 题,第 1011 题,第 1283 题。

Sort

如果想深刻理解多路快排 请参见LC75
想理解桶排序和基数排序 LC164
摆动排序:LC324

Union Find

灵活使用并查集的思想,**熟练掌握并查集的模板,模板中有两种并查集的实现方式,一种是路径压缩 + 秩优化的版本,另外一种是计算每个集合中元素的个数 + 最大集合元素个数的版本,**这两种版本都有各自使用的地方。能使用第一类并查集模板的题目有:第 128 题,第 130 题,第 547 题,第 684 题,第 721 题,第 765 题,第 778 题,第 839 题,第 924 题,第 928 题,第 947 题,第 952 题,第 959 题,第 990 题。能使用第二类并查集模板的题目有:第 803 题,第 952 题。第 803 题秩优化和统计集合个数这些地方会卡时间,如果不优化,会 TLE。
并查集是一种思想,有些题需要灵活使用这种思想,而不是死套模板,如第 399 题,这一题是 stringUnionFind,利用并查集思想实现的。这里每个节点是基于字符串和 map 的,而不是单纯的用 int 节点编号实现的。
**有些题死套模板反而做不出来,**比如第 685 题,这一题不能路径压缩和秩优化,因为题目中涉及到有向图,需要知道节点的前驱节点,如果路径压缩了,这一题就没法做了。这一题不需要路径压缩和秩优化。
灵活的抽象题目给的信息,将给定的信息合理的编号,使用并查集解题,并用 map 降低时间复杂度,如第 721 题,第 959 题。
关于地图,砖块,网格的题目,可以新建一个特殊节点,将四周边缘的砖块或者网格都 union() 到这个特殊节点上。第 130 题,第 803 题。
能用并查集的题目,一般也可以用 DFS 和 BFS 解答,只不过时间复杂度会高一点。

Segment Tree

线段树的经典数组实现写法。将合并两个节点 pushUp 逻辑抽象出来了,可以实现任意操作(常见的操作有:加法,取 max,min 等等)。第 218 题,第 303 题,第 307 题,第 699 题。
计数线段树的经典写法。第 315 题,第 327 题,第 493 题。
线段树的树的实现写法。第 715 题,第 732 题。
区间懒惰更新。第 218 题,第 699 题。
离散化。离散化需要注意一个特殊情况:假如三个区间为 [1,10] [1,4] [6,10],离散化后 x[1]=1,x[2]=4,x[3]=6,x[4]=10。第一个区间为 [1,4],第二个区间为 [1,2],第三个区间为 [3,4],这样一来,区间一 = 区间二 + 区间三,这和离散前的模型不符,离散前,很明显,区间一 > 区间二 + 区间三。正确的做法是:在相差大于 1 的数间加一个数,例如在上面 1 4 6 10 中间加 5,即可 x[1]=1,x[2]=4,x[3]=5,x[4]=6,x[5]=10。这样处理之后,区间一是 1-5 ,区间二是 1-2 ,区间三是 4-5 。
灵活构建线段树。线段树节点可以存储多条信息,合并两个节点的 pushUp 操作也可以是多样的。第 850 题,第 1157 题。

你可能感兴趣的:(Dive,Deep,in,Algorithm,LeetCode)