炸弹袭击

题目:
给定一个二维矩阵, 每一个格子可能是一堵墙 W,或者 一个敌人 E 或者空 0 (数字 ‘0’), 返回你可以用一个炸弹杀死的最大敌人数. 炸弹会杀死所有在同一行和同一列没有墙阻隔的敌人。 由于墙比较坚固,所以墙不会被摧毁.

样例
样例1

输入:
grid =[
“0E00”,
“E0WE”,
“0E00”
]
输出: 3
解释:
把炸弹放在 (1,1) 能杀3个敌人
样例2

输入:
grid =[
“0E00”,
“EEWE”,
“0E00”
]
输出: 2
解释:
P把炸弹放在 (0,0) 或 (0,3) 或 (2,0) 或 (2,3) 能杀2个敌人
注意事项
你只能在空的地方放置炸弹.

解题思路:首先思考坐标怎么求出能够炸死的敌人数,需要求出上下左右四个方向分别可以炸死的敌人数。比如向上,要求出当前坐标向上可以炸死多少敌人,就需要知道当前坐标的上面一个坐标可以炸死多少敌人,以此类推会发现这是一个重复子问题

public class Solution {
    /**
     * @param grid: Given a 2D grid, each cell is either 'W', 'E' or '0'
     * @return: an integer, the maximum enemies you can kill using one bomb
     */
    public int maxKilledEnemies(char[][] grid) {
        int n = grid.length;
        if(n == 0)
            return 0;
        int m = grid[0].length;
        if(m == 0)
            return 0;
        
        //数组定义:up[i][j]表示grid[i][j]向上能够炸死的敌人数
        int up[][] = new int[n][m];
        int down[][] = new int[n][m];
        int left[][] = new int[n][m];
        int right[][] = new int[n][m];
        
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                if(i == 0 || grid[i - 1][j] == 'W') {
                    up[i][j] = 0;
                } else if(grid[i - 1][j] == 'E'){
                    up[i][j] = up[i - 1][j] + 1;
                } else {
                    up[i][j] = up[i - 1][j];
                }
            }
        }
        
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                if(j == 0 || grid[i][j - 1] == 'W') {
                    left[i][j] = 0;
                } else if(grid[i][j - 1] == 'E') {
                    left[i][j] = left[i][j - 1] + 1;
                } else {
                    left[i][j] = left[i][j - 1];
                }
            }
        }
        
        for(int i = n - 1; i >= 0; i--) {
            for(int j = m - 1; j >= 0; j--) {
                if(i == n - 1 || grid[i + 1][j] == 'W') {
                    down[i][j] = 0;
                } else if(grid[i + 1][j] == 'E') {
                    down[i][j] = down[i + 1][j] + 1;
                } else {
                    down[i][j] = down[i + 1][j];
                }
            }
        }
        
        for(int i = n - 1; i >= 0; i--) {
            for(int j = m - 1; j >= 0; j--) {
                if(j == m - 1 || grid[i][j + 1] == 'W') {
                    right[i][j] = 0;
                } else if(grid[i][j + 1] == 'E') {
                    right[i][j] = right[i][j + 1] + 1;
                } else {
                    right[i][j] = right[i][j + 1];
                }
            }
        }
        
        int ans = 0;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                if(grid[i][j] == '0') {
                    ans = Math.max(ans, up[i][j] + down[i][j] + left[i][j] + right[i][j]);
                }
            }
        }
        
        return ans;
    }
}