Home - ShuweiLeung/Thinking GitHub Wiki
Welcome to wiki!
Array -> String -> Math -> Tree -> Hash Table -> Linked List -> Stack -> Two Pointers -> Heap -> Queue -> Greedy -> Dynamic Programming -> Depth-first Search -> Breadth-first Search -> Binary Search -> Backtracking -> Bit Manipulation -> Design(未全部做完)
- 单调栈
- Two pass(forward and backward): 从前向后和从后向前各一遍,通常用来求距离或DP问题(LC 821)。注意对二维数组,有从左上->右下和右下->左上两种pass的变种(LC 361)
- Two pointers
- Sliding window
- Dynamic programming,除了用数组进行DP状态存储以外,也可以用Map来存
- Greedy
- Stack
- PriorityQueue
- 如果原来数组中的数字为正,则将其置为负数与其他元素以作状态区分。
- Divide and Conquer,感觉LC 241很好,divide and conquer以及递归的结合
- Properties of BST. Inorder traversal.
- Recursive/DFS:通常都要设立一个visited数组,或者map和set也行(O(1)时间复杂度)
- Binary search
- BFS通常用来求最短距离(LC 1091)。求tree上距某个结点特定距离的结点,也需要先将树转化成无向图 LC 863
- Union Find
- Stack 先进先出特性
- 将数组作为水桶,访问一个元素则将对应位置的值+1或-1
- 对数组求和,计算missing number
- 用二进制的one bit作为掩码mask
- 用quick sort的哨兵作为分界线寻找kth largest element
- 当题目要求和数组index有关,且前一个change会造成数组原来后面的元素index的修改,可以从index较后的change开始处理,从而不影响前面的index改变
- 一种很好的利用字符串截取和hashmap并行判断subsequence的方法:792. Number of Matching Subsequences
- 在list中删除中间元素而不改变后面的元素索引的方法,是将其与list的最后一个元素调换,只修改最后一个元素的索引,然后删除最后一个元素即可(O(1)复杂度)
- Full Binary Tree如果根节点是n,左子树根节点则为2n,右子树根节点则为2n+1(一般题目若提到完全二叉树,通常会利用这个性质)
- 拓扑排序
- 从A到B以条件C访问可以看作从B到A以条件-C访问
- Trie字典树,TrieNode的children除了可以用int数组来表示以外,还可以用HashMap来表示,这样的话,可以表示的字符更多,不仅仅限于26个英文字母,如LC 642
- Two pointers滑动窗口,有时可以借用map来存储字符及该字符最后一次出现的位置索引(或者相反的关系),从而根据读取map直接滑动左窗口边界,如LC 3
- 一般,word集合问题一般都要将list变成set,方便O(1)时间复杂度进行判断
- 多叉树的序列化需要保存孩子结点的数量,因为孩子的个数是不定的,必须得存储该信息才可以反序列化(LC 428)
- 用一个最大堆和一个最小堆找中点median,[1,2,3] X [4,5,6]
- 链表若从最后一个尾结点逆向往前进行操作,可以用stack顺序存储链表结点,然后弹栈进行链表从后往前的逆操作
- 若要求连续数组的和为target的k倍,则只需要用map存储subarray sum对target取的余数以及对应sum的index即可,查找同样的余数是否在之前出现来判断有没有符合条件的子数组(LC 523)
- Stack虽然是先进后出,但对于输入的List可以从后向前将list中元素入栈,这样在出栈过程中实际上是从前向后遍历list的元素(LC 341)
- Outside-in方法,从外围向中心逼近处理元素
- 当前后多对多关系需要concatenate时,可以在当前层直接while循环遍历重复的片段处理即可(LC 1087),对于前后没有关联的一对多关系,可以使用dfs进行处理(LC 394)
- 求一个字符串的所有subsequence,dfs时,遍历的路径可以选择拼接当前的字符和不拼接当前的字符两种情况。对于第一种情况,当选择拼接当前的字符且之前的path为空时,包括了以当前字符为头新起一条搜索路径的情况。
- 在树上找距离某个node距离最近的leaf,可以先将树转化成图,然后从target node开始BFS找距离最近的leaf(LC 742)
- 文件路径的题目首先要想到用Stack方法去做
- 滚动数组可以降低空间复杂度
- 二分查无限大size的数组中元素,通过移位操作去锁定上下界(LC 702)
- 对于已排序的数组,每个数字读出现两次除了其中一个数字只出现了一次,可以使用二分搜索,根据配对数字的下标关系(i为奇数时应为i和i+1配对),来锁定二分查找的方向(LC 540)
- 反向思考,可以修改最多k个数字,就是维护窗口中不合法数字最多为k个(LC 1004)
- 通过bit manipulation来存储相关信息,例如字母总共有26个,那么给你一个字符串,你可以用二进制数来记录这个字符串中字符的存在情况,第i位二进制数代表从a开始算第i个字母是否存在(LC 318)
- 双向BFS,起点和终点都进行BFS,看有没交点,证明能否可达
- 树的结构也可以通过字符串(按先序中序或后序遍历的方式)来记录存储(LC 652)
- 稍复杂的DP都需要从片段长度为1开始累积求解,如LC video stitching和LC 813
- 批量比较判断subsequence的方法,将下一个要匹配的字符都存入一个list中,并不断更新每个字符串(LC 792)
- Djikstra's 迪杰斯特拉算法(LC 743)
- 有的时候math或者比较tricky的题目,需要考虑索引的奇偶性
- 我们可以用二进制移位操作的掩码来记录搜索过程中已visited的状态
- 要学会用TreeMap的API(LC 715)
- 在sorted list的基础上进行问题解答,如果一般的方法是O(n)时间复杂度,那么optimized的方法可能是O(logn)用二分搜索。
- Trie可以用来高效率的进行单词匹配及正则表达式pattern匹配,可以将目标words全部加入到Trie中从而简化后面的运算逻辑。