Friday, June 26, 2015

总结

general
遇到问题将算法模块化,可以假设一些方法已经给出或者之后再编写,可以加快找出主体思路的速度,减少浪费时间在细节上

*先想test case

-----------------------------------------------------------------------
tree

https://www.topcoder.com/community/data-science/data-science-tutorials/an-introduction-to-binary-search-and-red-black-trees/



#遇到prefix,stream of strings等,上tries

#(写法)递归时,在返回所需要的极值,传入pointer同时计算partial的值(如height,path sum)
例子:
LC #124 Binary Tree Maximum Path Sum
GeeksforGeeks: Diameter of a Binary Tree
# 另一种写法,返回的是partial的值,参数中pass by reference一个极值

#(写法) bfs,用一个queue和size来区分每一层,例子:level order traversal等等 #1 bst
遇到bst题目先考class Solution {
public:
    int minCost(vector<vector<int>>& costs) {
        int n = costs.size();
        if (n == 0) return 0;
        int dp0 = costs[0][0];
        int dp1 = costs[0][1];
        int dp2 = costs[0][2];
        
        for (int i = 1; i < n; i++) {
            int t0 = dp0, t1 = dp1, t2 = dp2;
            dp0 = costs[i][0] + min(t1,t2);
            dp1 = costs[i][1] + min(t2,t0);
            dp2 = costs[i][2] + min(t1,t0);
        }

        return min(min(dp0,dp1),dp2);
    }
};虑in place遍历方法:pre - in - post(#94,#144,#145,#105,#106)
注:#94跟#173的单stack写法

dfs寻找路径,可以用一个大小为树的高度的vector跟int level表示当前高度

-----------------------------------------------------------------------
string
palindrome(LC: #5, #9, #125, #131, #132, #214), 可以预先用DP检测palindrome存值

-----------------------------------------------------------------------
dp
from Tara: 局部最优解关键词:最大,最小,至少,至多

从recursion引出dp

string类的,先从小的test case下手,如(ab,b) 
例题:LC #115,distinct subsequence

矩阵类(见矩阵词条)

多层dp,paint house

-----------------------------------------------------------------------
array
直接上:双指针和hashmap
-----------------------------------------------------------------------
subsets / combination
此类问题有2种解题思路(LC #90,#77,#39, #40)
假如有集合{1,2,3,4,5}
#1 传统combination
递归: 第一层递归,每次取{}空集合,各插入一元素。第二层递归,此时集合内含有一个元素,每次插入index大于它的元素
第一层{1},{2}, {3}, {4}, {5}
第二层{1, 2}, {1,3},{1,4}, {1,5},{2, 3}, {2,4},{2,5},{3,4}.....
第三层{1,2,3},{1,2,4},{1,2,5},{1,3,4},{1,3,5}.....{2,3,4},{2,3,5}......
.....

遍历:看LC #90 Subsets代码

#2 类似bitmap
集合内的每个元素都有2种情况--被包括在集合或不被包括在集合
递归:见Google interview questions #2,第2题

遍历:
subsets的总个数为 2^原集合的大小,设一个loop大小为总个数,把每一个从0 到 总个数 - 1(看做二进制)的数作为bit mask,来跟原集合对应
看LC #90 Subsets代码
-----------------------------------------------------------------------
math
#1加减法, LC #2,#66,#67, 
#1 各种类型与integer的暂时互相转化
#2 carry可以用来当sum用
#3 loop的终止条件配合loop内的判断
#4 dummy node


--------------------------------------------------------------------
矩阵
矩阵路径:如果只能往下和往右走的话,用recursion或者dp (LC #130, #200)
如果增加其他方向,Dijkstra和普通的BFS都可以适用 (Google interview questions #3, 后几题) (Google interview questions #2, 第5题follow up)


矩阵中找最大的sub矩阵:
LC:#85 Maximal Rectangle, #221 Maximal Square, Google interview #6 倒数第2道http://www.geeksforgeeks.org/dynamic-programming-set-27-max-sum-rectangle-in-a-2d-matrix/

------------------------------------------------------------------------
Linked List
快慢指针的使用:
如下循环结束后,slow将指向中点(奇数个)或指向后半部分的起点(偶数个)
ListNode *slow = head, *fast = head;
while (fast != NULL) {
    fast = fast->next;
    if (fast != NULL) {
        fast = fast->next;
        slow = slow->next;
    }
}

-------------------------------------------------------------------------
点跟线段,坐标
sort x或y
closest pair of points(code 见coursera 第一章)

找median
example: 见google interview #5 第1,2部分 的oil pipe,朋友矩阵

------------------------------------------------------------------
随机性的题(待写)
general,高中概率论:某个值最终被选中的概率 = 当前被选中的概率 * 之前没被选中的概率

扑克牌http://www.geeksforgeeks.org/shuffle-a-given-array/

用ran(5)生成ran(7): 二维数组
{[1,2,3,4,5],
  [6,7,1,2,3],
  [4,5,6,7,1],
  [2,3,4,5,6],
  [7,0,0,0,0]}

Reservoir sampling: Google interview questions #4 倒数第2题
https://en.wikipedia.org/wiki/Reservoir_sampling
http://www.geeksforgeeks.org/reservoir-sampling/

-------------------------------------------------------------
Sorting
Merge sort: count inversions, LC # 148,#88,#23,#21
radix sort/count sort/bucket sort: LC #164

------------------------------------------------------------------
游戏算法
https://www.topcoder.com/community/data-science/data-science-tutorials/%20algorithm-games/
定理:
  • All terminal positions are losing.
  • If a player is able to move to a losing position then he is in a winning position.
  • If a player is able to move only to the winning positions then he is in a losing position.

第一个例子:The Game of Nim
当所有piles的size xor之后如果是0的话,当前为losing position,因为输的条件是0,从0开始第一步肯定会让xor的值变成非0。
如果当前xor为非0,则从最左侧的1的个数为奇开始,改变当前的pile,可使xor变成0

------------------------------------------------------------
Binary search
(写法)
while (left <= right) {
    ....
}
if target is not found, after the search, "left" is always the index where target should be inserted. and "right" equals to "left - 1"
LC #35, #74, #240

----------------------------------------
Divide and conquer
切两半,需要的值可能在任意一边,或者是横跨两边。
example:closest pair of points, lc #53 maximum subarray,

-------------------------------------------------------
Recursion
(写法)对于求各种集合的题(如permutation,combination,求所有path),sub-set可以用pass by reference来代替,减少递归时的空间,LC #113 Path Sum II

---------------------------------------------------
Graph
bfs: 例题:person找血缘关系,第2部分第8题

Union find: 代码,google interview #7 第一部分第1题
http://blog.csdn.net/dm_vincent/article/details/7655764
The input is a sequence of pairs of integers, where each integer represents an object of some type and we are to interpret the pair p q as meaning p is connected to q. We assume that "is connected to" is an equivalence relation:
case study:
http://algs4.cs.princeton.edu/15uf/

-----------------------------------
Interval的题
排序,merge或者split,见google#6,飞哥的题。LC的那几道

------------------------------------------
sliding window的题
当发现至少一个window符合要求时,以后的操作都要维护、保持这个window的合法性
例子: LC #3 Longest Substring Without Repeating Characters, #76 Minimum Window Substring 等等

--------------------------------------------------
Longest sub-string/sequence 类
考虑DP,lintcode上有一套



No comments:

Post a Comment