LeetCode 361 - Bomb Enemy


https://discuss.leetcode.com/topic/10/bomb-enemy/
Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return the maximum enemies you can kill using one bomb.
The bomb kills all the enemies in the same row and column from the planted point until it hits the wall since the wall is too strong to be destroyed.
Note that you can only put the bomb at an empty cell.
Example:
For the given grid

0 E 0 0
E 0 W E
0 E 0 0

return 3. (Placing a bomb at (1,1) kills 3 enemies)
Main goal is how to use less space
X. https://discuss.leetcode.com/topic/48565/short-o-mn-time-o-n-space-solution
Walk through the matrix. At the start of each non-wall-streak (row-wise or column-wise), count the number of hits in that streak and remember it. O(mn) time, O(n) space.
int maxKilledEnemies(vector<vector<char>>& grid) {
    int m = grid.size(), n = m ? grid[0].size() : 0;
    int result = 0, rowhits, colhits[n];
    for (int i=0; i<m; i++) {
        for (int j=0; j<n; j++) {
            if (!j || grid[i][j-1] == 'W') {
                rowhits = 0;
                for (int k=j; k<n && grid[i][k] != 'W'; k++)
                    rowhits += grid[i][k] == 'E';
            }
            if (!i || grid[i-1][j] == 'W') {
                colhits[j] = 0;
                for (int k=i; k<m && grid[k][j] != 'W'; k++)
                    colhits[j] += grid[k][j] == 'E';
            }
            if (grid[i][j] == '0')//
                result = max(result, rowhits + colhits[j]);
        }
    }
    return result;
}
https://discuss.leetcode.com/topic/48742/simple-dp-solution-in-java
only need to store one killed enemies value for a row and an array of each column;
if current grid value is W, this means previous stored value becomes invalid, you need to recalculate.
I think it is O(m * n). Although there is another for loop k inside for loops of i and j. It just calculates the enemies in advance. In the end, it will traverse this grid once to compute the enemies that are killed.

 it is little a DP-like SOLUTION, the only place col[], which is storing col enemies count, is only updated once for consecutive enemies column, and reused for later calculation (when there is '0', where bomb can be planted)


 public int maxKilledEnemies(char[][] grid) {
    if(grid == null || grid.length == 0 ||  grid[0].length == 0) return 0;
    int max = 0;
    int row = 0;
    int[] col = new int[grid[0].length];
    for(int i = 0; i<grid.length; i++){
        for(int j = 0; j<grid[0].length;j++){
            if(grid[i][j] == 'W') continue;
            if(j == 0 || grid[i][j-1] == 'W'){
                 row = killedEnemiesRow(grid, i, j);
            }
            if(i == 0 || grid[i-1][j] == 'W'){
                 col[j] = killedEnemiesCol(grid,i,j);
            }
            if(grid[i][j] == '0'){//
                max = (row + col[j] > max) ? row + col[j] : max;
            }
        }

    }
    
    return max;
}

//calculate killed enemies for row i from column j
private int killedEnemiesRow(char[][] grid, int i, int j){
    int num = 0;
    while(j <= grid[0].length-1 && grid[i][j] != 'W'){
        if(grid[i][j] == 'E') num++;
        j++;
    }
    return num;
}
//calculate killed enemies for  column j from row i
private int killedEnemiesCol(char[][] grid, int i, int j){
    int num = 0;
    while(i <= grid.length -1 && grid[i][j] != 'W'){
        if(grid[i][j] == 'E') num++;
        i++;
    }
    return num;
}
X. O(mn) space
https://discuss.leetcode.com/topic/48603/java-straightforward-solution-dp-o-mn-time-and-space
The code might be a little bit long and there should exist more elegant one.
However the idea of this very straightforward. We do simply two traversals. One from upper left to bottom right, for each spot we compute enemies to its left and up including itself. The other traversal is from bottom right to upper left, we compute enemies to its right and down and in the same time we add them up all to find the maxKill.
    public int maxKilledEnemies(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
        int m = grid.length, n = grid[0].length;
        Spot[][] spots = new Spot[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                spots[i][j] = new Spot();
                if (grid[i][j] == 'W') {
                    continue;
                }
                spots[i][j].up = (i == 0 ? 0 : spots[i - 1][j].up) + (grid[i][j] == 'E' ? 1 : 0);
                spots[i][j].left = (j == 0 ? 0 : spots[i][j - 1].left) + (grid[i][j] == 'E' ? 1 : 0);
            }
        }
        
        int maxKill = 0;
        for (int i = m - 1; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                if (grid[i][j] == 'W') {
                    continue;
                }
                spots[i][j].bottom = (i == m - 1 ? 0 : spots[i + 1][j].bottom) + (grid[i][j] == 'E' ? 1 : 0);
                spots[i][j].right = (j == n - 1 ? 0 : spots[i][j + 1].right) + (grid[i][j] == 'E' ? 1 : 0);
                
                if (grid[i][j] == '0') {
                    maxKill = Math.max(maxKill, spots[i][j].up + spots[i][j].left + spots[i][j].bottom + spots[i][j].right);
                }
            }
        }
        return maxKill;
    }
class Spot {
    int up; // enemies to its up including itself
    int left; // enemies to its left including itself
    int bottom;
    int right;
}
X.
https://discuss.leetcode.com/topic/49109/straightforward-o-mn-java-solution-49ms
public int maxKilledEnemies(char[][] grid) {
    int rowNum = grid.length;
    if (rowNum == 0) return 0;
    int colNum = grid[0].length;

    int[][] fromBottom = new int[rowNum][colNum];
    int[][] fromRight = new int[rowNum][colNum];

    for (int i = rowNum - 1; i >= 0; i--) {
        for (int j = colNum - 1; j >= 0; j--) {
            int enemy = grid[i][j] == 'E' ? 1 : 0;
            if (grid[i][j] != 'W') {
                fromBottom[i][j] = (i == rowNum - 1) ? enemy : fromBottom[i+1][j] + enemy;
                fromRight[i][j] = (j == colNum - 1) ? enemy : fromRight[i][j+1] + enemy;
            }
            else {
                fromBottom[i][j] = 0;
                fromRight[i][j] = 0;
            }
        }
    }

    int[] fromTop = new int[colNum];
    int[] fromLeft = new int[rowNum];
    int max = 0;

    for (int i = 0; i < rowNum; i++) {
        for (int j = 0; j < colNum; j++) {
            if (grid[i][j] != '0') {
                fromTop[j] = grid[i][j] == 'W' ? 0 : fromTop[j] + 1;
                fromLeft[i] = grid[i][j] == 'W' ? 0 : fromLeft[i] + 1;
            }
            else {
                int num = fromTop[j] + fromLeft[i] + fromBottom[i][j] + fromRight[i][j];
                max = Math.max(num, max);
            }
        }
    }
    return max;
}
http://www.cnblogs.com/grandyang/p/5599289.html
建立四个累加数组v1, v2, v3, v4,其中v1是水平方向从左到右的累加数组,v2是水平方向从右到左的累加数组,v3是竖直方向从上到下的累加数组,v4是竖直方向从下到上的累加数组,我们建立好这个累加数组后,对于任意位置(i, j),其可以炸死的最多敌人数就是v1[i][j] + v2[i][j] + v3[i][j] + v4[i][j],最后我们通过比较每个位置的累加和,就可以得到结果
    int maxKilledEnemies(vector<vector<char>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        int m = grid.size(), n = grid[0].size(), res = 0;
        vector<vector<int>> v1(m, vector<int>(n, 0)), v2 = v1, v3 = v1, v4 = v1;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                int t = (j == 0 || grid[i][j] == 'W') ? 0 : v1[i][j - 1];
                v1[i][j] = grid[i][j] == 'E' ? t + 1 : t;
            }
            for (int j = n - 1; j >= 0; --j) {
                int t = (j == n - 1 || grid[i][j] == 'W') ? 0 : v2[i][j + 1];
                v2[i][j] = grid[i][j] == 'E' ? t + 1 : t;
            }
        }
        for (int j = 0; j < n; ++j) {
            for (int i = 0; i < m; ++i) {
                int t = (i == 0 || grid[i][j] == 'W') ? 0 : v3[i - 1][j];
                v3[i][j] = grid[i][j] == 'E' ? t + 1 : t;
            }
            for (int i = m - 1; i >= 0; --i) {
                int t = (i == m - 1 || grid[i][j] == 'W') ? 0 : v4[i + 1][j];
                v4[i][j] = grid[i][j] == 'E' ? t + 1 : t;
            }
        }
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == '0') {
                    res = max(res, v1[i][j] + v2[i][j] + v3[i][j] + v4[i][j]);
                }
            }
        }
        return res;
    }

https://discuss.leetcode.com/topic/52170/share-my-java-codes
X. https://leetcode.com/discuss/109116/short-o-mn-solution
这种解法比较省空间,写法也比较简洁,需要一个rowCnt变量,用来记录到下一个墙之前的敌人个数。还需要一个数组colCnt,其中colCnt[j]表示第j列到下一个墙之前的敌人个数。算法思路是遍历整个数组grid,对于一个位置grid[i][j],对于水平方向,如果当前位置是开头一个或者前面一个是墙壁,我们开始从当前位置往后遍历,遍历到末尾或者墙的位置停止,计算敌人个数。对于竖直方向也是同样,如果当前位置是开头一个或者上面一个是墙壁,我们开始从当前位置向下遍历,遍历到末尾或者墙的位置停止,计算敌人个数。有了水平方向和竖直方向敌人的个数,那么如果当前位置是0,表示可以放炸弹,我们更新结果res即可

https://discuss.leetcode.com/topic/48565/short-o-mn-solution
int maxKilledEnemies(vector<vector<char>>& grid) {
    int m = grid.size(), n = m ? grid[0].size() : 0;
    int result = 0, rowhits, colhits[n];
    for (int i=0; i<m; i++) {
        for (int j=0; j<n; j++) {
            if (!j || grid[i][j-1] == 'W') {
                rowhits = 0;
                for (int k=j; k<n && grid[i][k] != 'W'; k++)
                    rowhits += grid[i][k] == 'E';
            }
            if (!i || grid[i-1][j] == 'W') {
                colhits[j] = 0;
                for (int k=i; k<m && grid[k][j] != 'W'; k++)
                    colhits[j] += grid[k][j] == 'E';
            }
            if (grid[i][j] == '0')
                result = max(result, rowhits + colhits[j]);
        }
    }
    return result;
}
https://discuss.leetcode.com/topic/48577/short-java-accepted-solution-55ms
public int maxKilledEnemies(char[][] grid) {
    if (grid == null || grid.length == 0 || grid[0].length == 0) {
        return 0;
    }
    int ret = 0;
    int row = grid.length;
    int col = grid[0].length;
    int rowCache = 0;
    int[] colCache = new int[col];
    for (int i = 0;i < row; i++) {
        for (int j = 0; j < col; j++) {
            if (j == 0 || grid[i][j-1] == 'W') {
                rowCache = 0;
                for (int k = j; k < col && grid[i][k] != 'W'; k++) {
                    rowCache += grid[i][k] == 'E' ? 1 : 0;
                }
            }
            if (i == 0 || grid[i-1][j] == 'W') {
                colCache[j] = 0;
                for (int k = i;k < row && grid[k][j] != 'W'; k++) {
                    colCache[j] += grid[k][j] == 'E' ? 1 :0;
                }
            }
            if (grid[i][j] == '0') {
                ret = Math.max(ret, rowCache + colCache[j]);
            }
        }
    }
    return ret;
}

http://dartmooryao.blogspot.com/2016/06/leetcode-361-bomb-enemy.html
My idea is to create a 2D matrix, and go from Left, Right, Top, and Down to calculate the count. Then add the count into the 2D matrix.

This solution is better because the code looks much shorter.

Idea:
(1) Use a 1D array to store the current count of the previous cols, and another int variable to store the count from the left.
(2) Use two for loops to visit all elements in the matrix.
(3) When the left of current position is a wall, we reset the rowHit variable to 0. Then we use a for loop that start from current position to the right, adding the count of E to the rowHit. Until we hit a wall.
(4) When the top col is a wall, we reset the colHit to be zero. Then use the same way to calculate the colHit to the end of col.
(5) If the current position is a '0', we compare the rowHit+colHit with the max result.
    public int maxKilledEnemies(char[][] grid) {
        if(grid.length==0){ return 0; }
        int rowNo = grid.length, colNo = grid[0].length;
        int[] colHit = new int[colNo];
        int rowHit = 0;
        int result = 0;
       
        for(int i=0; i<rowNo; i++){
            for(int j=0; j<colNo; j++){
                if(j==0 || grid[i][j-1]=='W'){
                    rowHit = 0;
                    for(int k=j; k<colNo && grid[i][k] != 'W'; k++){
                        if(grid[i][k]=='E'){ rowHit++; }
                    }
                }
               
                if(i==0 || grid[i-1][j]=='W'){
                    colHit[j] = 0;
                    for(int k=i; k<rowNo && grid[k][j] != 'W'; k++){
                        if(grid[k][j]=='E'){ colHit[j]++; }
                    }
                }
               
                if(grid[i][j]=='0'){
                    result = Math.max(result, rowHit+colHit[j]);
                }
            }
        }
       
        return result;
    }


Walk through the matrix. At the start of each non-wall-streak (row-wise or column-wise), count the number of hits in that streak and remember it. O(mn) time, O(n) space.
int maxKilledEnemies(vector<vector<char>>& grid) {
    int m = grid.size(), n = m ? grid[0].size() : 0;
    int result = 0, rowhits, colhits[n];
    for (int i=0; i<m; i++) {
        for (int j=0; j<n; j++) {
            if (!j || grid[i][j-1] == 'W') {
                rowhits = 0;
                for (int k=j; k<n && grid[i][k] != 'W'; k++)
                    rowhits += grid[i][k] == 'E';
            }
            if (!i || grid[i-1][j] == 'W') {
                colhits[j] = 0;
                for (int k=i; k<m && grid[k][j] != 'W'; k++)
                    colhits[j] += grid[k][j] == 'E';
            }
            if (grid[i][j] == '0')
                result = max(result, rowhits + colhits[j]);
        }
    }
    return result;
}
https://leetcode.com/discuss/109134/short-java-accepted-solution-55ms
public int maxKilledEnemies(char[][] grid) { if (grid == null || grid.length == 0 || grid[0].length == 0) { return 0; } int ret = 0; int row = grid.length; int col = grid[0].length; int rowCache = 0; int[] colCache = new int[col]; for (int i = 0;i < row; i++) { for (int j = 0; j < col; j++) { if (j == 0 || grid[i][j-1] == 'W') { rowCache = 0; for (int k = j; k < col && grid[i][k] != 'W'; k++) { rowCache += grid[i][k] == 'E' ? 1 : 0; } } if (i == 0 || grid[i-1][j] == 'W') { colCache[j] = 0; for (int k = i;k < row && grid[k][j] != 'W'; k++) { colCache[j] += grid[k][j] == 'E' ? 1 :0; } } if (grid[i][j] == '0') { ret = Math.max(ret, rowCache + colCache[j]); } } } return ret; }
X. Brute Force
https://discuss.leetcode.com/topic/51035/super-straightforward-java-solution/
Isn't this a Brute force way with Time complexity O(m^2 + n^2) ?
https://leetcode.com/discuss/109110/simple-java-solution-easy-to-understand
public int maxKilledEnemies(char[][] grid) { if (grid == null || grid.length == 0) return 0; int ret=0; for (int i=0; i<grid.length; i++) { for (int j=0; j<grid[0].length; j++) { if (grid[i][j] != '0') continue; ret = Math.max(ret, countKilled(i, j, grid)); } } return ret; } int countKilled(int row, int col, char[][] grid) { int ret=0; for (int i=row; i<grid.length && grid[i][col] != 'Y'; i++) { if (grid[i][col] == 'X') ret++; } for (int i=row; i>=0 && grid[i][col] != 'Y'; i--) { if (grid[i][col] == 'X') ret++; } for (int i=col; i<grid[0].length && grid[row][i] != 'Y'; i++) { if (grid[row][i] == 'X') ret++; } for (int i=col; i>=0 && grid[row][i] != 'Y'; i--) { if (grid[row][i] == 'X') ret++; } return ret; }

https://discuss.leetcode.com/topic/50374/java-dp-solultion-o-mn-time-o-mn-space-beats-90
Using only O(mn) memory for additional grid (not as perfect as (O(m) space solutions given by other users but anyway..) we can solve this problem through O(4mn) iterations. We just need to scan the grid from left to right and accumulate the sum of enemies by dp[i][j] from left since the last wall. Then we do the same from top to bottom, from right to left and finally from bottom to top. On each iteration we increase the dp[i][j] value by cumulative sum.
  public int maxKilledEnemies(char[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;

        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m][n];

        // from left to right
        for (int i = 0; i < m; i++) {
            int current = 0;
            for (int j = 0; j < n; j++) 
                current = process(grid, dp, i, current, j);
        }
        // from top to bottom
        for (int j = 0; j < n; j++) {
            int current = 0;
            for (int i = 0; i < m; i++) 
                current = process(grid, dp, i, current, j);
        }
        // from right to left
        for (int i = 0; i < m; i++) {
            int current = 0;
            for (int j = n - 1; j >= 0; j--) 
                current = process(grid, dp, i, current, j);
        }
        int ans = 0;
        // from bottom to top
        for (int j = 0; j < n; j++) {
            int current = 0;
            for (int i = m - 1; i >= 0; i--) {
                current = process(grid, dp, i, current, j);
                if (grid[i][j] == '0')  ans = Math.max(ans, dp[i][j]);
            }
        }

        return ans;
    }

    private int process(char[][] c, int[][] dp, int i, int current, int j) {
        if (c[i][j] == 'W') current = 0;
        if (c[i][j] == 'E') current++;
        dp[i][j] += current;
        return current;
    }

https://all4win78.wordpress.com/2016/07/24/leetcode-361-bomb-enemy/
如果遍历数组,找到’0’之后再向四个方向拓展数’E’的个数,一定会超时。一般的解决方法就是DP,用一个cache来存下部分结果来避免重复运算。我这里用的是一个m*2的array,叫做enemyCount,来储存每一行的结果。enemyCount[i][0]储存了第i行某一个’W’的位置,enemyCount[i][1]储存了enemyCount[i][0]所标识的’W’到之前一个’W’之间’E’的个数,初始化的时候enemyCount[i][0] = -1,enemyCount[i][1] = 0。
然后我按照列遍历,因为之前enemyCount是按照行来储存的,如果发现当前j大于了enemyCount[i][0]的值,我们就要更新enemyCount。同时,每列在遍历的时候都会有一个临时的变量,叫做colEnemy,用来记录在当前的列两个’W’之间有多少’E’,每次遇到’W’就需要更新这个值。每次遇到一个’0’的时候,我们就可以把这个临时变量和enemyCount[i][1]的值加起来,然后视情况更新我们的全局最大值。
初始:
361_1
在检查grid[1][1]的时候,此时我们正在考虑第二列,所以enemyCount上的数值已经更新过了,第一行是4和1,因为第一行没有’W’,所以我们第一个终止的地方就是4这个位置,(-1, 4)范围内一共一个’E’;第二行是2和1,因为grid[1][2] = ‘W’,而且在(-1, 2)范围内是一个’E’;第三行同第一行。colEnemy也可以直接看出是2,因为第二列在(-1, 3)范围内有两个’E’。
361_2
    public int maxKilledEnemies(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
         
        int[][] enemyCount = new int[grid.length][2];
        for (int i = 0; i < enemyCount.length; i++) {
            enemyCount[i][0] = -1;
        }
         
        int max = 0;
        for (int j = 0; j < grid[0].length; j++) {
            int colEnemy = countColEnemy(grid, j, 0);
            for (int i = 0; i < grid.length; i++) {
                if (grid[i][j] == '0') {
                    if (j > enemyCount[i][0]) {
                        update(enemyCount, grid, i, j);
                    }
                    max = Math.max(colEnemy + enemyCount[i][1], max);
                }
                if (grid[i][j] == 'W') {
                    colEnemy = countColEnemy(grid, j, i + 1);
                }
            }
        }
        return max;
    }
     
    private void update(int[][] enemyCount, char[][] grid, int i, int j) {
        int count = 0;
        int k = enemyCount[i][0] + 1;
        while (k < grid[0].length && (grid[i][k] != 'W' || k < j)) {
            if (grid[i][k] == 'E') {
                count += 1;
            }
            if (grid[i][k] == 'W') {
                count = 0;
            }
            k += 1;
        }
        enemyCount[i][0] = k;
        enemyCount[i][1] = count;
    }
     
    private int countColEnemy(char[][] grid, int j, int start) {
        int count = 0;
        int i = start;
        while (i < grid.length && grid[i][j] != 'W') {
            if (grid[i][j] == 'E') {
                count += 1;
            }
            i += 1;
        }
        return count;
    }

X.
https://fishercoder.com/2016/07/12/bomb-enemy/
https://discuss.leetcode.com/topic/53511/straightforward-java-solution-with-space-complex-o-1
https://discuss.leetcode.com/topic/51035/super-straightforward-java-solution
public int maxKilledEnemies(char[][] grid) {
    int m = grid.length;
    if(grid == null || m == 0) return 0;
    int n = grid[0].length;
    
    int[][] max = new int[m][n];
    
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            
            if(grid[i][j] == '0'){
                int count = 0;
                
                //count all possible hits in its upward direction
                for(int k = j-1; k >= 0; k--){
                    if(grid[i][k] == 'E') {
                        count++;
                    } else if(grid[i][k] == 'W') {
                        break;
                    }
                }
                
                //count all possible hits in its downward direction
                for(int k = j+1; k < n; k++){
                    if(grid[i][k] == 'E') {
                        count++;
                    } else if(grid[i][k] == 'W') {
                        break;
                    }
                }
                
                //count all possible hits in its right direction
                for(int k = i+1; k < m; k++){
                    if(grid[k][j] == 'E') {
                        count++;
                    } else if(grid[k][j] == 'W') {
                        break;
                    }
                }
                
                //count all possible hits in its left direction
                for(int k = i-1; k >= 0; k--){
                    if(grid[k][j] == 'E') {
                        count++;
                    } else if(grid[k][j] == 'W') {
                        break;
                    }
                }
                
                max[i][j] = count;
                
            } 
        }
    }
    
    int result = 0;
    
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            if(max[i][j] > result) result = max[i][j];
        }
    }
    return result;
}
follow up是如果这个地图很大,很多点都是空的没东西,你怎么优化你的算法。楼主想了下稀疏矩阵乘法那道题就说用一个二维矩阵矩阵来记录每一行中,各个位置中不为0的列数和其对应的值,然后遍历这个新矩阵

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