【多次過】【座標型】Lintcode 553. 炸彈襲擊
阿新 • • 發佈:2018-11-07
給一個二維矩陣, 每一個格子都可能是一堵牆 W
, 一個敵人 E
或者空 0
(數字 '0'), 返回你可以用一個炸彈殺死的最大敵人數. 炸彈會殺死所有在同一行和同一列沒有牆阻隔的敵人, 因為牆比較堅固難以摧毀.
樣例
給一個矩陣:
0 E 0 0
E 0 W E
0 E 0 0
返回 3
.(在(1, 1)處放炸彈可以殺死 3 個敵人)
注意事項
你只能在空的地方放置炸彈.
解題思路:
每個炸彈可以往四個方向傳播,我們可以分析一個方向,然後舉一反三,即如果在一個空地放一個炸彈,最多向上炸死多少敵人。
確定狀態:
我們假設有敵人或有牆的格子也能放炸彈。
有敵人的格子:格子的敵人被炸死,並繼續向上爆炸
有牆的格子:炸彈不能炸死任何敵人
在(1,j)格放一個炸彈,它向上能炸死的敵人數是:
若(i,j)格為空地:(i-1,j)格向上能炸死的敵人數
若(i,j)格為敵人:(i-1,j)格向上能炸死的敵人數 + 1
若(i,j)格為牆:0
子問題:
需要知道(i-1,j)格放一個炸彈向上能炸死的敵人數。
狀態:dp[i][j]表示(i,j)格放一個炸彈向上能炸死的敵人數
狀態方程:
初始條件:與第0行的dp值和格子內容相關
dp[0][j] = 0 , 若(0,j)格不是敵人
dp[0][j] = 1 , 若(0,j)格是敵人
四個方向:
上面只說明瞭向上的炸死敵人數,一共四個方向,同理可類似的計算其餘方向,注意計算順序會有改變。
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) { // write your code here 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]; int[][] res = new int[m][n]; //up for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ if(grid[i][j] == 'W') dp[i][j] = 0; else{ dp[i][j] = 0; if(grid[i][j] == 'E') dp[i][j] = 1; if(i-1 >= 0) dp[i][j] = dp[i-1][j]; } res[i][j] += dp[i][j]; } } //down for(int i=m-1; i>=0; i--){ for(int j=0; j<n; j++){ if(grid[i][j] == 'W') dp[i][j] = 0; else{ dp[i][j] = 0; if(grid[i][j] == 'E') dp[i][j] = 1; if(i+1 < m) dp[i][j] = dp[i+1][j]; } res[i][j] += dp[i][j]; } } //left for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ if(grid[i][j] == 'W') dp[i][j] = 0; else{ dp[i][j] = 0; if(grid[i][j] == 'E') dp[i][j] = 1; if(j-1 >= 0) dp[i][j] = dp[i][j-1]; } res[i][j] += dp[i][j]; } } //right for(int i=0; i<m; i++){ for(int j=n-1; j>=0; j--){ if(grid[i][j] == 'W') dp[i][j] = 0; else{ dp[i][j] = 0; if(grid[i][j] == 'E') dp[i][j] = 1; if(j+1 < n) dp[i][j] = dp[i][j+1]; } res[i][j] += dp[i][j]; } } int result = 0; for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ if(grid[i][j] == '0'){ if(res[i][j] > result) result = res[i][j]; } } } return result; } }