LeetCode 1145 - Binary Tree Coloring Game


https://leetcode.com/problems/binary-tree-coloring-game/
Two players play a turn based game on a binary tree.  We are given the root of this binary tree, and the number of nodes n in the tree.  n is odd, and each node has a distinct value from 1 to n.
Initially, the first player names a value x with 1 <= x <= n, and the second player names a value y with 1 <= y <= n and y != x.  The first player colors the node with value x red, and the second player colors the node with value y blue.
Then, the players take turns starting with the first player.  In each turn, that player chooses a node of their color (red if player 1, blue if player 2) and colors an uncolored neighbor of the chosen node (either the left child, right child, or parent of the chosen node.)
If (and only if) a player cannot choose such a node in this way, they must pass their turn.  If both players pass their turn, the game ends, and the winner is the player that colored more nodes.
You are the second player.  If it is possible to choose such a y to ensure you win the game, return true.  If it is not possible, return false.

Example 1:

Input: root = [1,2,3,4,5,6,7,8,9,10,11], n = 11, x = 3
Output: true
Explanation: The second player can choose the node with value 2.

Constraints:
  • root is the root of a binary tree with n nodes and distinct node values from 1 to n.
  • n is odd.
  • 1 <= x <= n <= 100
https://leetcode.com/problems/binary-tree-coloring-game/discuss/350570/JavaC%2B%2BPython-Simple-recursion-and-Follow-Up
The first player colors a node,
there are at most 3 nodes connected to this node.
Its left, its right and its parent.
Take this 3 nodes as the root of 3 subtrees.
The second player just color any one root,
and the whole subtree will be his.
And this is also all he can take,
since he cannot cross the node of the first player.

Explanation

count will recursively count the number of nodes,
in the left and in the right.
n - left - right will be the number of nodes in the "subtree" of parent.
Now we just need to compare max(left, right, parent) and n / 2

Complexity

Time O(N)
Space O(height) for recursion
    int left, right, val;
    public boolean btreeGameWinningMove(TreeNode root, int n, int x) {
        val = x;
        count(root);
        return Math.max(Math.max(left, right), n - left - right - 1) > n / 2;
    }

    private int count(TreeNode node) {
        if (node == null) return 0;
        int l = count(node.left), r = count(node.right);
        if (node.val == val) {
            left = l;
            right = r;
        }
        return l + r + 1;
    }

Fun Moment of Follow-up:

Alex and Lee are going to play this turned based game.
Alex draw the whole tree. root and n will be given.
Now Lee says he want to color the first node.
  1. Return true if Lee can ensure his win, otherwise return false
  2. Could you find the set all the nodes, that Lee can ensure he wins the game?
  3. What is the complexity of your solution?

For the follow up:
Calculate the count of three parts(left, right, parent) for each node. Then if any sum of two parts among above three is larger than the rest, then Lee can ensure his win on this node.
Because Lee choose this node, whichever Alex choose, left, right or parent, it will be smaller than the sum of left two parts, in this case, Alex is always lose.

https://leetcode.com/problems/binary-tree-coloring-game/discuss/367682/Simple-Clean-Java-Solution
When you find the selected node, there are three different paths you can block: left right parent In order to guarantee your win, one of those paths should include more nodes than the sum of other two paths.
.
public boolean btreeGameWinningMove(TreeNode root, int n, int x) {
 if(root == null) return false;

 if(root.val == x){
  int left = count(root.left);
  int right = count(root.right);
  int parent = n - (left+right+1);

  return parent > (left + right) || left > (parent + right) || right > (left + parent);
 }

 return btreeGameWinningMove(root.left, n, x) || btreeGameWinningMove(root.right, n, x);
}

private int count(TreeNode node){
 if(node == null) return 0;
 return count(node.left) + count(node.right) + 1;
}

https://leetcode.com/problems/binary-tree-coloring-game/discuss/380525/Java-Solution-with-explanation
CASE 1
We calcaulate the number of nodes in the subtree rooted at X, and if the number of nodes in in this subtree is greater then the count of rest of the nodes in the tree we return false.
CASE 2
In this approach, we calcaculate the number of nodes in the left and right sub tree of the tree rooted at X, now comes the tricky part, we would choose the maximumOf(leftSubtreeCount, rightSubtreeCount) as Y. Now since Y is one of the child of X, so the nodes above X would be coloured by X. In short,
Count of X = mininmumOf(leftSubtreeCount, rightSubtreeCount) + rest of the nodes in tree
Counf of Y = maximumOf(leftSubtreeCount, rightSubtreeCount)

if(Count of X < Count of Y){
 return true;
}
In the end with return the OR of the cases.
CODE
class Solution {      
    public boolean btreeGameWinningMove(TreeNode root, int n, int x) {
                
        // Case 1
        TreeNode nodex = findX(root, x);
        int countofx = countNodes(nodex);
        int countofy = n - countofx;
        boolean case1 = countofy>countofx;
        
        //Case 2
        boolean case2 = helper(root,x,n,0);

        return case1 || case2; 
    }
    
    
    public static boolean helper(TreeNode root, int x, int n, int count){
        if(root==null){
            return false;
        }      
        if(root.val == x){
            int leftsubtree = countNodes(root.left);
            int rightsubtree = countNodes(root.right);
            
            int temp = Math.min(rightsubtree,leftsubtree) + n-(rightsubtree+leftsubtree+1);
            return temp < Math.max(leftsubtree,rightsubtree);
        }        
        boolean l = helper(root.left, x, n, count+1);
        boolean r = helper(root.right, x, n, count+1);
        return l||r;
    }
    
    //Method to find the node with value X
    public static TreeNode findX(TreeNode root, int x){
        if(root==null){
            return null;
        }        
        if(root.val == x){
            return root;
        }
        TreeNode lft = findX(root.left,x);
        if(lft!=null){
            return lft;
        }
        return findX(root.right,x);
    }
    
    
    //Method to count number of nodes
    public static int countNodes(TreeNode root){
        if(root==null){
            return 0;
        }
        return 1+ countNodes(root.left)+countNodes(root.right);
    }
http://www.debugger.wiki/article/html/1565027161636814
    // 三个部分的最大值
    int maxCount = 0;
    // 记录二叉树每个节点DFS的值
    int[] sizeOfNode = new int[150];
    
    // dfs 做法
    // 叶子节点置为1 其父节点为子节点之和+1
    int dfs(TreeNode root, int x) {
        int v = root.val;
        sizeOfNode[v] = 1;
        
        if (root.left != null) {
            int c = dfs(root.left, x);
            sizeOfNode[v] += c;
            // 如果当前节点为对方选取点, c就表示是其左子节点DFS的值
            if (x == v) {
                maxCount = Math.max(maxCount, c);
            }
        }
        if (root.right != null) {
            int c = dfs(root.right, x);
            sizeOfNode[v] += c;
            // 如果当前节点为对方选取点, c就表示是其右子节点DFS的值
            if (x == v) {
                maxCount = Math.max(maxCount, c);
            }
        }
        return sizeOfNode[v];
    }
    
    public boolean btreeGameWinningMove(TreeNode root, int n, int x) {
        // 对二叉树进行DFS
        dfs(root, x);
        // 比对父节点 与左右子节点的最大值
        maxCount = Math.max(maxCount, n-sizeOfNode[x]);
        // 如果己方遍历节点数大于 n/2 则对方必然小于己方
        return maxCount > n/2;
    }

https://www.acwing.com/solution/LeetCode/content/3430/
有两位玩家参与了一场在二叉树上进行的回合制游戏。游戏中,给出二叉树的根结点 root,树上总共有 n 个结点,且 n 为奇数,其中每个结点上的值从 1 到 n 各不相同。
最开始时,一号玩家取一个值 x 满足 1 <= x <= n,二号玩家也取一个值 y 满足 1 <= y <= n 且 y != x
一号玩家给值为 x 的结点染上红色,而二号玩家给值为 y 的结点染上蓝色。
之后两位玩家轮流进行操作,每一回合,玩家选择一个他之前涂好颜色结结点,将所选结点一个 未着色 的邻结点(即左右子结点、或父结点)进行染色。
如果当前玩家无法找到这样的结点来染色时,他的回合就会被跳过。
若两个玩家都没有可以染色的结点时,游戏结束。着色结点最多的那位玩家获得胜利️。
现在,假设你是二号玩家,根据所给出的输入,假如存在一个 y 值可以确保你赢得这场游戏,则返回 true;若无法获胜,就请返回 false
  • 二叉树的根结点为 root,树上由 n 个结点,结点上的值从 1 到 n 各不相同。
  • n 为奇数。
  • 1 <= x <= n <= 100
(贪心,深度优先遍历) O(n)
  1. 对于二号玩家,最多有三个备选的位置,一个是 x 的左结点,一个是右结点,或者是父结点。
  2. 我们通过一次深度优先遍历,求出 x 左右子树的大小,以及除了 x 为根的子树之外的大小,就分别可以得到三个备选所代表的被蓝色染色结点个数。
  3. 找到最大结点数的备选位置即可。

时间复杂度

  • 每个位置仅访问一次,故时间复杂度为 O(n)

空间复杂度

  • 由于采用了递归,系统需要消耗 O(h) 的空间复杂度,其中 h 为树的最大高度。
    int solve(TreeNode* rt, int n, int x, int& tot) {
        if (rt == NULL)
            return 0;

        int ls = solve(rt -> left, n, x, tot);
        int rs = solve(rt -> right, n, x, tot);

        if (rt -> val == x)
            tot = max(max(ls, rs), n - ls - rs - 1);

        return ls + rs + 1;
    }

    bool btreeGameWinningMove(TreeNode* root, int n, int x) {
        int tot = 0;
        solve(root, n, x, tot);
        return tot > n / 2;
    }

LeetCode 1146 - Snapshot Array


https://leetcode.com/problems/snapshot-array/
Implement a SnapshotArray that supports the following interface:
  • SnapshotArray(int length) initializes an array-like data structure with the given length.  Initially, each element equals 0.
  • void set(index, val) sets the element at the given index to be equal to val.
  • int snap() takes a snapshot of the array and returns the snap_id: the total number of times we called snap() minus 1.
  • int get(index, snap_id) returns the value at the given index, at the time we took the snapshot with the given snap_id

Example 1:
Input: ["SnapshotArray","set","snap","set","get"]
[[3],[0,5],[],[0,6],[0,0]]
Output: [null,null,0,null,5]
Explanation: 
SnapshotArray snapshotArr = new SnapshotArray(3); // set the length to be 3
snapshotArr.set(0,5);  // Set array[0] = 5
snapshotArr.snap();  // Take a snapshot, return snap_id = 0
snapshotArr.set(0,6);
snapshotArr.get(0,0);  // Get the value of array[0] with snap_id = 0, return 5
Constraints:
  • 1 <= length <= 50000
  • At most 50000 calls will be made to setsnap, and get.
  • 0 <= index < length
  • 0 <= snap_id < (the total number of times we call snap())
  • 0 <= val <= 10^9
X. Binary search
https://leetcode.com/problems/snapshot-array/discuss/350562/JavaPython-Binary-Search
    TreeMap<Integer, Integer>[] A;
    int snap_id = 0;
    public SnapshotArray(int length) {
        A = new TreeMap[length];
        for (int i = 0; i < length; i++) {
            A[i] = new TreeMap<Integer, Integer>();
            A[i].put(0, 0);
        }
    }

    public void set(int index, int val) {
        A[index].put(snap_id, val);
    }

    public int snap() {
        return snap_id++;
    }

    public int get(int index, int snap_id) {
        return A[index].floorEntry(snap_id).getValue();
    }
https://leetcode.com/problems/snapshot-array/discuss/350648/Java-O(1)-snap-O(logN)-getset-using-TreeMap
    List<TreeMap<Integer, Integer>> arr;
    int currId = 0;

    public SnapshotArray(int length) {
        arr = new ArrayList();
        
        for (int i = 0; i < length; i++) {
            arr.add(i, new TreeMap<Integer, Integer>());
            arr.get(i).put(0, 0);
        }
    }
    
    public void set(int index, int val) {
        arr.get(index).put(currId, val);
    }
    
    public int snap() {
        return currId++;
    }
    
    public int get(int index, int snap_id) {
        return arr.get(index).floorEntry(snap_id).getValue();
    }
https://leetcode.com/problems/snapshot-array/discuss/350574/Java-Two-codes-w-analysis-store-difference-by-HashMap-and-TreeMap-respectively.
Store to a HashMap the set() results since previous snapshot.
Analysis:
Time: Each call of get() cost O(snap_id), othersO(1);
Space: Total cost O(n), where n is number of calls of set().
    private List<Map<Integer, Integer>> shot;
    private Map<Integer, Integer> diff;
    
    public SnapshotArray(int length) {
        shot  = new ArrayList<>(length);
        diff  = new HashMap<>(length);
    }
    
    public void set(int index, int val) {
        diff.put(index, val);
    }
    
    public int snap() {
        shot.add(diff);
        diff = new HashMap<>();
        return shot.size() - 1;
    }
    
    public int get(int index, int snap_id) {
        for (int i = snap_id; i >= 0; --i)
             if (shot.get(i).containsKey(index))   
                 return shot.get(i).get(index); 
        return 0;
    }

Method 2: TreeMap
Store the set() result together with current snapshot count to the TreeMap of the specified index.
Analysis:
Time: Instantiation cost O(length), each call of get()/set() cost O(log(count))snap() O(1);
Space: Total cost O(length + count).
    private int count;
    private List<TreeMap<Integer, Integer>> shot = new ArrayList<>();
    
    public SnapshotArray(int length) {
        IntStream.range(0, length).forEach(i -> { shot.add(new TreeMap<>()); });
    }
    
    public void set(int index, int val) {
        shot.get(index).put(count, val);
    }
    
    public int snap() {
        return count++;
    }
    
    public int get(int index, int snap_id) {
        Integer key = shot.get(index).floorKey(snap_id);
        return key == null ? 0 : shot.get(index).get(key);
    }
https://www.cnblogs.com/lz87/p/11314526.html
Each index has its own treemap to store all needed values of different snap ids information. For a key value pair(k, v) in an index's treemap, it means starting from snap id k, until there is a newer snap, the value is v. ThisInstead of copy the whole array,
we can only record the changes of set.

Explanation

The idea is, the whole array can be large,
and we may take the snap tons of times.
(Like you may always ctrl + S twice)
Instead of record the history of the whole array,
we will record the history of each cell.
And this is the minimum space that we need to record all information.
For each A[i], we will record its history.
With a snap_id and a its value.
When we want to get the value in history, just binary search the time point.

Complexity

Time O(logS)
Space O(S)
where S is the number of set called.
SnapshotArray(int length) is O(N) time
set(int index, int val) is O(1) in Python and O(logSnap) in Java
snap() is O(1)
get(int index, int snap_id) is O(logSnap) representation helps achieve the following properties.
1. O(N) init, O(logS) get and set, where N is the total number of indices and S is the total number of snaps for an index.
2. If there is no value update at index i for consecutive snap shots, there will be only a snap_id to value mapping. When setting a new value at index i, it first check the last entry of its map, this is the latest value prior to this update operation. Only insert a new mapping if the new value is the same with the previous value, which means starting from this new snap id, the value is the new value.  
3. When calling the get method, it tries to find the a key-value mapping associated with the greatest key less than or equal to the given key snap id. 
复制代码
class SnapshotArray {
    private TreeMap<Integer, Integer>[] snapMap;
    private int snapId = 0;
    public SnapshotArray(int length) {
        snapMap = new TreeMap[length];
        for (int i = 0; i < length; i++) {
            snapMap[i] = new TreeMap<Integer, Integer>();
            snapMap[i].put(0, 0);
        }
    }

    public void set(int index, int val) {
        Map.Entry<Integer, Integer> lastEntry = snapMap[index].lastEntry();
        if(val != lastEntry.getValue()) {
            snapMap[index].put(snapId, val);
        }        
    }

    public int snap() {
        return snapId++;
    }

    public int get(int index, int snap_id) {
        return snapMap[index].floorEntry(snap_id).getValue();
    }

https://www.acwing.com/solution/LeetCode/content/3431/
实现支持下列接口的快照数组:
  • SnapshotArray(int length) 初始化一个与指定长度相等的类似于数组的数据结构。初始时,每个元素都等于 0
  • void set(index, val) 会将指定索引 index 处的元素设置为 val
  • int snap() 获取该数组的快照,并返回快照的编号 snap_id(快照号是调用 snap() 的总次数减去 1)。
  • int get(index, snap_id) 根据指定的 snap_id 选择快照,并返回该快照指定索引 index 的值。
(数据结构,二分)
  1. 我们在普通数组的基础上进行改造,每个位置都存储一个新动态数组,存储每个版本(如果有)下的更改。
  2. 初始时,我们建立长度为 length 的数组,每个位置是一个长度为 1 的数组,仅保存版本号 0 和 元素 0 的一个数对。
  3. 修改时,我们去 index 位置的数组中的最后一个位置,如果那个位置的版本号等于当前计数器的版本号,则直接修改元素值;否则新插入一个数对,记录当前版本号和元素值。
  4. 快照时,直接更新计数器。
  5. 查询时,我们得到那个位置的数组,然后开始二分,找到小于等于待查询版本的最大版本的那个数对,返回数对的元素值即可。

时间复杂度

  • 初始化时间复杂度为 O(length)
  • 修改元素的时间复杂度为 O(1)
  • 快照的时间复杂度为 O(1)
  • 查询的时间复杂度最坏为 O(logS),其中 S 为快照的次数。

空间复杂度

  • 最坏需要 O(length+Q) 的空间,其中 Q 为操作的总次数

    vector<vector<pair<int, int>>> arr;
    int counter;

    SnapshotArray(int length) {
        arr.resize(length, vector<pair<int, int>>(1));
        for (int i = 0; i < length; i++)
            arr[i][0] = make_pair(0, 0);
        counter = 0;
    }

    void set(int index, int val) {
        auto &x = arr[index][arr[index].size() - 1];
        if (x.first == counter)
            x.second = val;
        else {
            arr[index].emplace_back(make_pair(counter, val));
        }
    }

    int snap() {
        return counter++;
    }

    int get(int index, int snap_id) {
        auto &v = arr[index];
        int l = 0, r = v.size() - 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (snap_id >= v[mid + 1].first)
                l = mid + 1;
            else
                r = mid;
        }
        return v[l].second;
    }

X.
https://www.codetd.com/en/article/6973297
Each location to open up a space that is only saved in this location 变化
because of the number of changes in each location is not the same
when you want value, they look for less input snap_id latest变化
  • Use List + Map data structures to build an array of snapshots
List changes in store for each position
value after the change: TreeMap single storage changes in key: snapshot number value
Use List + Map
  • Examples of its structure

ArrayList + TreeMap

class SnapshotArray {
    // List 存储每个位置的变动情况
    // TreeMap 存储单次变动情况 key:快照编号 value:变动后的值
    // [index,[(snapId, val), (snapId, val)...]]
    List<TreeMap<Integer, Integer>> list = new ArrayList<>();
    // 当前快照编号
    int snapId = 0;

    // 初始化
    public SnapshotArray(int length) {
        snapId = 0;
        // 开始每个位置全为0
        for (int i = 0; i < length; i++) {
            TreeMap<Integer, Integer> t = new TreeMap<>();
            t.put(snapId, 0);
            list.add(t);
        }
    }
    
    public void set(int index, int val) {
        // 重复就覆盖
        list.get(index).put(snapId, val);
    }
    
    public int snap() {
        int res = snapId;
        snapId++;
        return res;
    }
    
    /**
     * 难点 
     * 需要在TreeMap的key值中寻找小于快照编号snap_id的数据
     * 
     * 这里取巧使用了自带的方法 
     * floorEntry(key) 找到key值接近snap_id的实体Entry
     **/
    public int get(int index, int snap_id) {
        TreeMap<Integer, Integer> t = list.get(index);
        return t.floorEntry(snap_id).getValue();
    }
X. https://leetcode.com/problems/snapshot-array/discuss/383030/Java-Binary-Search-Solution
  // int[0]: snapId, int[1]:val
  private List<int[]>[] snapshots;
  private int snapId;

  public SnapshotArray(int length) {
    snapId = 0;
    snapshots = new List[length];
    
    for (int i = 0; i < length; i++) {
      List<int[]> snapListEachItem = new ArrayList<>();
      snapListEachItem.add(new int[] {0, 0});
      snapshots[i] = snapListEachItem;
    }
    
  }

  public void set(int index, int val) {
    List<int[]> snapsOfIndex = snapshots[index];
    int[] lastSnap = snapsOfIndex.get(snapsOfIndex.size() - 1);
    
    // If last snap id is less than current id then add a new snap.
    if (lastSnap[0] < snapId) {
      snapsOfIndex.add(new int[] {snapId, val});
      return;
    }
    
    lastSnap[0] = snapId;
    lastSnap[1] = val;
  }

  public int snap() {
    return snapId++;
  }

  public int get(int index, int snap_id) {
    List<int[]> snaps = snapshots[index];
    return binarySearch(snaps, snap_id);
  }
  
  private int binarySearch(List<int[]> snaps, int snapId) {
    int low = 0, high = snaps.size() - 1;
    
    while (low <= high) {
      int mid = low + (high - low) / 2;
      
      if (snaps.get(mid)[0] < snapId) {
        low = mid + 1;
      } else if (snaps.get(mid)[0] > snapId) {
        high = mid - 1;
      } else {
        return snaps.get(mid)[1];
      }
    }
    
    return low == 0 ? snaps.get(0)[1] : snaps.get(low - 1)[1];
  }

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts