361. Bomb Enemy 🔒
Problem Description
You are given an m x n
matrix grid
where each cell contains one of three possible values:
'W'
represents a wall'E'
represents an enemy'0'
represents an empty cell
Your task is to find the maximum number of enemies you can kill by placing exactly one bomb in the grid.
Rules for bomb placement and explosion:
- A bomb can only be placed in an empty cell (marked as
'0'
) - When a bomb explodes, it kills all enemies in the same row and column as the bomb
- The explosion extends in all four directions (up, down, left, right) from the bomb's position
- The explosion stops when it hits a wall (
'W'
) in any direction - walls block the explosion from continuing further - Walls cannot be destroyed by the explosion
For example, if you place a bomb at position (i, j)
:
- It kills all enemies to the left of
(i, j)
in rowi
until a wall is encountered - It kills all enemies to the right of
(i, j)
in rowi
until a wall is encountered - It kills all enemies above
(i, j)
in columnj
until a wall is encountered - It kills all enemies below
(i, j)
in columnj
until a wall is encountered
The goal is to determine the optimal placement of a single bomb to maximize the number of enemy kills and return that maximum count. If no empty cells exist in the grid, return 0
.
Intuition
The key insight is that for each empty cell, we need to count how many enemies would be killed if we placed a bomb there. A bomb kills enemies in four directions: left, right, up, and down from its position, stopping at walls.
A naive approach would be to iterate through each empty cell and then scan in all four directions to count enemies. However, this would involve redundant calculations since we'd be counting the same enemies multiple times for different bomb positions.
The clever observation is that we can precompute the enemy counts for each position more efficiently. For any position (i, j)
, the total enemies killed equals:
- Enemies to the left in row
i
(until hitting a wall) - Enemies to the right in row
i
(until hitting a wall) - Enemies above in column
j
(until hitting a wall) - Enemies below in column
j
(until hitting a wall)
We can build up these counts using dynamic programming passes:
-
Row-wise counting: For each row, we make two passes:
- Left-to-right pass: Count enemies seen so far from the left, resetting when we hit a wall
- Right-to-left pass: Count enemies seen so far from the right, resetting when we hit a wall
-
Column-wise counting: For each column, we make two passes:
- Top-to-bottom pass: Count enemies seen so far from above, resetting when we hit a wall
- Bottom-to-top pass: Count enemies seen so far from below, resetting when we hit a wall
By accumulating these counts in a separate grid g
, each cell g[i][j]
will contain the total number of enemies that would be killed if a bomb were placed at position (i, j)
. The trick is that when we encounter an enemy during our passes, we increment our running count, and this count gets added to all positions we visit until we hit a wall.
Finally, we simply find the maximum value in g
where the corresponding position in the original grid is an empty cell '0'
.
Solution Approach
The solution implements the precomputation strategy using a 2D auxiliary grid g
to store the enemy count for each position. Here's how the implementation works:
1. Initialize the auxiliary grid:
g = [[0] * n for _ in range(m)]
This creates an m x n
grid initialized with zeros to accumulate enemy counts.
2. Process each row (horizontal enemy counting):
For each row i
, we make two passes:
Left-to-right pass:
t = 0
for j in range(n):
if grid[i][j] == 'W':
t = 0 # Reset count when hitting a wall
elif grid[i][j] == 'E':
t += 1 # Increment count when finding an enemy
g[i][j] += t # Add current count to this position
The variable t
tracks enemies encountered from the left. When we hit a wall, we reset t
to 0. When we encounter an enemy, we increment t
. The current value of t
is added to g[i][j]
.
Right-to-left pass:
t = 0
for j in range(n - 1, -1, -1):
if grid[i][j] == 'W':
t = 0
elif grid[i][j] == 'E':
t += 1
g[i][j] += t
Similar logic but traversing from right to left, accumulating enemies from the right direction.
3. Process each column (vertical enemy counting):
For each column j
, we make two passes:
Top-to-bottom pass:
t = 0
for i in range(m):
if grid[i][j] == 'W':
t = 0
elif grid[i][j] == 'E':
t += 1
g[i][j] += t
Bottom-to-top pass:
t = 0
for i in range(m - 1, -1, -1):
if grid[i][j] == 'W':
t = 0
elif grid[i][j] == 'E':
t += 1
g[i][j] += t
After these four passes, each cell g[i][j]
contains the total number of enemies that would be killed by placing a bomb at position (i, j)
.
4. Find the maximum for empty cells:
return max(
[g[i][j] for i in range(m) for j in range(n) if grid[i][j] == '0'],
default=0,
)
We iterate through all positions, filter for empty cells ('0'
), and return the maximum value from g
. The default=0
handles the case when no empty cells exist.
Time Complexity: O(m * n)
- We make exactly 4 passes through the grid.
Space Complexity: O(m * n)
- We use an auxiliary grid of the same size as the input.
The elegance of this solution lies in avoiding redundant calculations. Instead of checking all four directions for each empty cell individually, we precompute the enemy counts for all positions simultaneously through systematic grid traversals.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example to illustrate the solution approach.
Consider this 3x4 grid:
W 0 E 0 E 0 E E 0 W 0 E
We'll create an auxiliary grid g
(initially all zeros) to accumulate enemy counts:
0 0 0 0 0 0 0 0 0 0 0 0
Step 1: Process rows left-to-right
Row 0: W 0 E 0
- Start with t=0
- Position (0,0): Wall → reset t=0, g[0][0] += 0 = 0
- Position (0,1): Empty → g[0][1] += 0 = 0
- Position (0,2): Enemy → increment t=1, g[0][2] += 1 = 1
- Position (0,3): Empty → g[0][3] += 1 = 1
Row 1: E 0 E E
- Start with t=0
- Position (1,0): Enemy → increment t=1, g[1][0] += 1 = 1
- Position (1,1): Empty → g[1][1] += 1 = 1
- Position (1,2): Enemy → increment t=2, g[1][2] += 2 = 2
- Position (1,3): Enemy → increment t=3, g[1][3] += 3 = 3
Row 2: 0 W 0 E
- Start with t=0
- Position (2,0): Empty → g[2][0] += 0 = 0
- Position (2,1): Wall → reset t=0, g[2][1] += 0 = 0
- Position (2,2): Empty → g[2][2] += 0 = 0
- Position (2,3): Enemy → increment t=1, g[2][3] += 1 = 1
After left-to-right pass:
0 0 1 1 1 1 2 3 0 0 0 1
Step 2: Process rows right-to-left
Row 0: W 0 E 0
- Start with t=0 from right
- Position (0,3): Empty → g[0][3] += 0 = 1
- Position (0,2): Enemy → increment t=1, g[0][2] += 1 = 2
- Position (0,1): Empty → g[0][1] += 1 = 1
- Position (0,0): Wall → reset t=0, g[0][0] += 0 = 0
Row 1: E 0 E E
- Start with t=0 from right
- Position (1,3): Enemy → increment t=1, g[1][3] += 1 = 4
- Position (1,2): Enemy → increment t=2, g[1][2] += 2 = 4
- Position (1,1): Empty → g[1][1] += 2 = 3
- Position (1,0): Enemy → increment t=3, g[1][0] += 3 = 4
Row 2: 0 W 0 E
- Start with t=0 from right
- Position (2,3): Enemy → increment t=1, g[2][3] += 1 = 2
- Position (2,2): Empty → g[2][2] += 1 = 1
- Position (2,1): Wall → reset t=0, g[2][1] += 0 = 0
- Position (2,0): Empty → g[2][0] += 0 = 0
After right-to-left pass:
0 1 2 1 4 3 4 4 0 0 1 2
Step 3: Process columns top-to-bottom
Column 0: W E 0
- Start with t=0
- Position (0,0): Wall → reset t=0, g[0][0] += 0 = 0
- Position (1,0): Enemy → increment t=1, g[1][0] += 1 = 5
- Position (2,0): Empty → g[2][0] += 1 = 1
Column 1: 0 0 W
- Start with t=0
- Position (0,1): Empty → g[0][1] += 0 = 1
- Position (1,1): Empty → g[1][1] += 0 = 3
- Position (2,1): Wall → reset t=0, g[2][1] += 0 = 0
Column 2: E E 0
- Start with t=0
- Position (0,2): Enemy → increment t=1, g[0][2] += 1 = 3
- Position (1,2): Enemy → increment t=2, g[1][2] += 2 = 6
- Position (2,2): Empty → g[2][2] += 2 = 3
Column 3: 0 E E
- Start with t=0
- Position (0,3): Empty → g[0][3] += 0 = 1
- Position (1,3): Enemy → increment t=1, g[1][3] += 1 = 5
- Position (2,3): Enemy → increment t=2, g[2][3] += 2 = 4
After top-to-bottom pass:
0 1 3 1 5 3 6 5 1 0 3 4
Step 4: Process columns bottom-to-top
Column 0: W E 0
- Start with t=0 from bottom
- Position (2,0): Empty → g[2][0] += 0 = 1
- Position (1,0): Enemy → increment t=1, g[1][0] += 1 = 6
- Position (0,0): Wall → reset t=0, g[0][0] += 0 = 0
Column 1: 0 0 W
- Start with t=0 from bottom
- Position (2,1): Wall → reset t=0, g[2][1] += 0 = 0
- Position (1,1): Empty → g[1][1] += 0 = 3
- Position (0,1): Empty → g[0][1] += 0 = 1
Column 2: E E 0
- Start with t=0 from bottom
- Position (2,2): Empty → g[2][2] += 0 = 3
- Position (1,2): Enemy → increment t=1, g[1][2] += 1 = 7
- Position (0,2): Enemy → increment t=2, g[0][2] += 2 = 5
Column 3: 0 E E
- Start with t=0 from bottom
- Position (2,3): Enemy → increment t=1, g[2][3] += 1 = 5
- Position (1,3): Enemy → increment t=2, g[1][3] += 2 = 7
- Position (0,3): Empty → g[0][3] += 2 = 3
Final grid g
:
0 1 5 3 6 3 7 7 1 0 3 5
Step 5: Find maximum for empty cells
Empty cells in original grid are at positions: (0,1), (0,3), (1,1), (2,0), (2,2)
Their corresponding values in g
:
- Position (0,1): 1
- Position (0,3): 3
- Position (1,1): 3
- Position (2,0): 1
- Position (2,2): 3
The maximum is 3, which can be achieved by placing a bomb at positions (0,3), (1,1), or (2,2).
Solution Implementation
1class Solution:
2 def maxKilledEnemies(self, grid: List[List[str]]) -> int:
3 # Handle empty grid
4 if not grid or not grid[0]:
5 return 0
6
7 rows, cols = len(grid), len(grid[0])
8
9 # Create a 2D array to store total enemies that can be killed from each position
10 enemies_killed = [[0] * cols for _ in range(rows)]
11
12 # Count enemies that can be killed horizontally (left-to-right and right-to-left)
13 for row in range(rows):
14 # Left to right pass: count enemies to the left
15 enemy_count = 0
16 for col in range(cols):
17 if grid[row][col] == 'W':
18 # Wall blocks the explosion, reset counter
19 enemy_count = 0
20 elif grid[row][col] == 'E':
21 # Found an enemy, increment counter
22 enemy_count += 1
23 # Add enemies that would be killed from the left
24 enemies_killed[row][col] += enemy_count
25
26 # Right to left pass: count enemies to the right
27 enemy_count = 0
28 for col in range(cols - 1, -1, -1):
29 if grid[row][col] == 'W':
30 # Wall blocks the explosion, reset counter
31 enemy_count = 0
32 elif grid[row][col] == 'E':
33 # Found an enemy, increment counter
34 enemy_count += 1
35 # Add enemies that would be killed from the right
36 enemies_killed[row][col] += enemy_count
37
38 # Count enemies that can be killed vertically (top-to-bottom and bottom-to-top)
39 for col in range(cols):
40 # Top to bottom pass: count enemies above
41 enemy_count = 0
42 for row in range(rows):
43 if grid[row][col] == 'W':
44 # Wall blocks the explosion, reset counter
45 enemy_count = 0
46 elif grid[row][col] == 'E':
47 # Found an enemy, increment counter
48 enemy_count += 1
49 # Add enemies that would be killed from above
50 enemies_killed[row][col] += enemy_count
51
52 # Bottom to top pass: count enemies below
53 enemy_count = 0
54 for row in range(rows - 1, -1, -1):
55 if grid[row][col] == 'W':
56 # Wall blocks the explosion, reset counter
57 enemy_count = 0
58 elif grid[row][col] == 'E':
59 # Found an enemy, increment counter
60 enemy_count += 1
61 # Add enemies that would be killed from below
62 enemies_killed[row][col] += enemy_count
63
64 # Find the maximum enemies that can be killed by placing a bomb in an empty cell
65 max_enemies = 0
66 for row in range(rows):
67 for col in range(cols):
68 if grid[row][col] == '0': # Can only place bomb in empty cells
69 max_enemies = max(max_enemies, enemies_killed[row][col])
70
71 return max_enemies
72
1class Solution {
2 public int maxKilledEnemies(char[][] grid) {
3 int rows = grid.length;
4 int cols = grid[0].length;
5
6 // Store the total enemies that can be killed from each position
7 int[][] enemyCount = new int[rows][cols];
8
9 // Count enemies in horizontal direction (left to right and right to left)
10 for (int row = 0; row < rows; row++) {
11 // Left to right pass: count enemies to the left of current position
12 int enemiesOnLeft = 0;
13 for (int col = 0; col < cols; col++) {
14 if (grid[row][col] == 'W') {
15 // Wall blocks the bomb, reset counter
16 enemiesOnLeft = 0;
17 } else if (grid[row][col] == 'E') {
18 // Found an enemy, increment counter
19 enemiesOnLeft++;
20 }
21 // Add enemies that would be killed from the left direction
22 enemyCount[row][col] += enemiesOnLeft;
23 }
24
25 // Right to left pass: count enemies to the right of current position
26 int enemiesOnRight = 0;
27 for (int col = cols - 1; col >= 0; col--) {
28 if (grid[row][col] == 'W') {
29 // Wall blocks the bomb, reset counter
30 enemiesOnRight = 0;
31 } else if (grid[row][col] == 'E') {
32 // Found an enemy, increment counter
33 enemiesOnRight++;
34 }
35 // Add enemies that would be killed from the right direction
36 enemyCount[row][col] += enemiesOnRight;
37 }
38 }
39
40 // Count enemies in vertical direction (top to bottom and bottom to top)
41 for (int col = 0; col < cols; col++) {
42 // Top to bottom pass: count enemies above current position
43 int enemiesAbove = 0;
44 for (int row = 0; row < rows; row++) {
45 if (grid[row][col] == 'W') {
46 // Wall blocks the bomb, reset counter
47 enemiesAbove = 0;
48 } else if (grid[row][col] == 'E') {
49 // Found an enemy, increment counter
50 enemiesAbove++;
51 }
52 // Add enemies that would be killed from above
53 enemyCount[row][col] += enemiesAbove;
54 }
55
56 // Bottom to top pass: count enemies below current position
57 int enemiesBelow = 0;
58 for (int row = rows - 1; row >= 0; row--) {
59 if (grid[row][col] == 'W') {
60 // Wall blocks the bomb, reset counter
61 enemiesBelow = 0;
62 } else if (grid[row][col] == 'E') {
63 // Found an enemy, increment counter
64 enemiesBelow++;
65 }
66 // Add enemies that would be killed from below
67 enemyCount[row][col] += enemiesBelow;
68 }
69 }
70
71 // Find the maximum enemies that can be killed by placing bomb in an empty cell
72 int maxEnemiesKilled = 0;
73 for (int row = 0; row < rows; row++) {
74 for (int col = 0; col < cols; col++) {
75 // Bomb can only be placed in empty cells (marked as '0')
76 if (grid[row][col] == '0') {
77 maxEnemiesKilled = Math.max(maxEnemiesKilled, enemyCount[row][col]);
78 }
79 }
80 }
81
82 return maxEnemiesKilled;
83 }
84}
85
1class Solution {
2public:
3 int maxKilledEnemies(vector<vector<char>>& grid) {
4 int rows = grid.size();
5 int cols = grid[0].size();
6
7 // Create a 2D array to store the total number of enemies that can be killed
8 // from each position (accumulating from all 4 directions)
9 vector<vector<int>> enemyCount(rows, vector<int>(cols, 0));
10
11 // Count enemies horizontally (left-to-right and right-to-left) for each row
12 for (int i = 0; i < rows; ++i) {
13 // Left to right pass: count enemies to the left of current position
14 int enemiesFromLeft = 0;
15 for (int j = 0; j < cols; ++j) {
16 if (grid[i][j] == 'W') {
17 // Wall blocks the explosion, reset counter
18 enemiesFromLeft = 0;
19 } else if (grid[i][j] == 'E') {
20 // Found an enemy, increment counter
21 ++enemiesFromLeft;
22 }
23 // Add enemies that would be killed from the left direction
24 enemyCount[i][j] += enemiesFromLeft;
25 }
26
27 // Right to left pass: count enemies to the right of current position
28 int enemiesFromRight = 0;
29 for (int j = cols - 1; j >= 0; --j) {
30 if (grid[i][j] == 'W') {
31 // Wall blocks the explosion, reset counter
32 enemiesFromRight = 0;
33 } else if (grid[i][j] == 'E') {
34 // Found an enemy, increment counter
35 ++enemiesFromRight;
36 }
37 // Add enemies that would be killed from the right direction
38 enemyCount[i][j] += enemiesFromRight;
39 }
40 }
41
42 // Count enemies vertically (top-to-bottom and bottom-to-top) for each column
43 for (int j = 0; j < cols; ++j) {
44 // Top to bottom pass: count enemies above current position
45 int enemiesFromTop = 0;
46 for (int i = 0; i < rows; ++i) {
47 if (grid[i][j] == 'W') {
48 // Wall blocks the explosion, reset counter
49 enemiesFromTop = 0;
50 } else if (grid[i][j] == 'E') {
51 // Found an enemy, increment counter
52 ++enemiesFromTop;
53 }
54 // Add enemies that would be killed from above
55 enemyCount[i][j] += enemiesFromTop;
56 }
57
58 // Bottom to top pass: count enemies below current position
59 int enemiesFromBottom = 0;
60 for (int i = rows - 1; i >= 0; --i) {
61 if (grid[i][j] == 'W') {
62 // Wall blocks the explosion, reset counter
63 enemiesFromBottom = 0;
64 } else if (grid[i][j] == 'E') {
65 // Found an enemy, increment counter
66 ++enemiesFromBottom;
67 }
68 // Add enemies that would be killed from below
69 enemyCount[i][j] += enemiesFromBottom;
70 }
71 }
72
73 // Find the maximum number of enemies that can be killed
74 // by placing a bomb in any empty cell ('0')
75 int maxEnemiesKilled = 0;
76 for (int i = 0; i < rows; ++i) {
77 for (int j = 0; j < cols; ++j) {
78 if (grid[i][j] == '0') {
79 // Only consider empty cells for bomb placement
80 maxEnemiesKilled = max(maxEnemiesKilled, enemyCount[i][j]);
81 }
82 }
83 }
84
85 return maxEnemiesKilled;
86 }
87};
88
1function maxKilledEnemies(grid: string[][]): number {
2 const rows: number = grid.length;
3 const cols: number = grid[0].length;
4
5 // Create a 2D array to store the total number of enemies that can be killed
6 // from each position (accumulating from all 4 directions)
7 const enemyCount: number[][] = Array(rows).fill(0).map(() => Array(cols).fill(0));
8
9 // Count enemies horizontally (left-to-right and right-to-left) for each row
10 for (let i = 0; i < rows; i++) {
11 // Left to right pass: count enemies to the left of current position
12 let enemiesFromLeft: number = 0;
13 for (let j = 0; j < cols; j++) {
14 if (grid[i][j] === 'W') {
15 // Wall blocks the explosion, reset counter
16 enemiesFromLeft = 0;
17 } else if (grid[i][j] === 'E') {
18 // Found an enemy, increment counter
19 enemiesFromLeft++;
20 }
21 // Add enemies that would be killed from the left direction
22 enemyCount[i][j] += enemiesFromLeft;
23 }
24
25 // Right to left pass: count enemies to the right of current position
26 let enemiesFromRight: number = 0;
27 for (let j = cols - 1; j >= 0; j--) {
28 if (grid[i][j] === 'W') {
29 // Wall blocks the explosion, reset counter
30 enemiesFromRight = 0;
31 } else if (grid[i][j] === 'E') {
32 // Found an enemy, increment counter
33 enemiesFromRight++;
34 }
35 // Add enemies that would be killed from the right direction
36 enemyCount[i][j] += enemiesFromRight;
37 }
38 }
39
40 // Count enemies vertically (top-to-bottom and bottom-to-top) for each column
41 for (let j = 0; j < cols; j++) {
42 // Top to bottom pass: count enemies above current position
43 let enemiesFromTop: number = 0;
44 for (let i = 0; i < rows; i++) {
45 if (grid[i][j] === 'W') {
46 // Wall blocks the explosion, reset counter
47 enemiesFromTop = 0;
48 } else if (grid[i][j] === 'E') {
49 // Found an enemy, increment counter
50 enemiesFromTop++;
51 }
52 // Add enemies that would be killed from above
53 enemyCount[i][j] += enemiesFromTop;
54 }
55
56 // Bottom to top pass: count enemies below current position
57 let enemiesFromBottom: number = 0;
58 for (let i = rows - 1; i >= 0; i--) {
59 if (grid[i][j] === 'W') {
60 // Wall blocks the explosion, reset counter
61 enemiesFromBottom = 0;
62 } else if (grid[i][j] === 'E') {
63 // Found an enemy, increment counter
64 enemiesFromBottom++;
65 }
66 // Add enemies that would be killed from below
67 enemyCount[i][j] += enemiesFromBottom;
68 }
69 }
70
71 // Find the maximum number of enemies that can be killed
72 // by placing a bomb in any empty cell ('0')
73 let maxEnemiesKilled: number = 0;
74 for (let i = 0; i < rows; i++) {
75 for (let j = 0; j < cols; j++) {
76 if (grid[i][j] === '0') {
77 // Only consider empty cells for bomb placement
78 maxEnemiesKilled = Math.max(maxEnemiesKilled, enemyCount[i][j]);
79 }
80 }
81 }
82
83 return maxEnemiesKilled;
84}
85
Time and Space Complexity
Time Complexity: O(m * n)
where m
is the number of rows and n
is the number of columns in the grid.
The algorithm consists of four main passes through the grid:
- First pass: Traverse each row from left to right, visiting all
m * n
cells once - Second pass: Traverse each row from right to left, visiting all
m * n
cells once - Third pass: Traverse each column from top to bottom, visiting all
m * n
cells once - Fourth pass: Traverse each column from bottom to top, visiting all
m * n
cells once - Final step: Find the maximum value among empty cells, which takes at most
O(m * n)
time
Total operations: 4 * (m * n) + O(m * n) = O(m * n)
Space Complexity: O(m * n)
The algorithm creates an auxiliary 2D array g
of size m × n
to store the cumulative enemy counts for each cell. This requires O(m * n)
additional space. The list comprehension in the final return statement creates a temporary list that could contain up to m * n
elements in the worst case (if all cells are empty), but this doesn't change the overall space complexity of O(m * n)
.
Common Pitfalls
1. Double-Counting Enemies
The Pitfall: A critical issue in the provided solution is that enemies are being counted multiple times. When we traverse from left-to-right and then right-to-left (or top-to-bottom and bottom-to-top), we're adding the enemy count to the cell itself when it contains an enemy ('E'). This causes each enemy to be counted in its own cell's total, which is incorrect since:
- Bombs can only be placed in empty cells ('0')
- An enemy at position (i,j) shouldn't contribute to the count at its own position
Example of the Bug:
Consider a row: ['0', 'E', '0']
- After left-to-right pass:
[0, 1, 1]
- After right-to-left pass:
[1, 2, 1]
The middle cell (containing 'E') shows a count of 2, but this position can't hold a bomb anyway.
The Solution: Only count enemies in the direction of traversal, not including the current cell if it's an enemy:
# Corrected left-to-right pass
enemy_count = 0
for col in range(cols):
if grid[row][col] == 'W':
enemy_count = 0
elif grid[row][col] == 'E':
enemy_count += 1
else: # Only update count for non-wall, non-enemy cells
enemies_killed[row][col] += enemy_count
2. Incorrect Enemy Accumulation Logic
The Pitfall: The current implementation adds enemies before encountering them in some passes, which gives incorrect results. For instance, in the left-to-right pass, we increment enemy_count
when we see an enemy and immediately add it to that enemy's position.
The Solution: Separate the counting logic more carefully:
def maxKilledEnemies(self, grid: List[List[str]]) -> int:
if not grid or not grid[0]:
return 0
rows, cols = len(grid), len(grid[0])
result = 0
row_kills = 0
col_kills = [0] * cols
for i in range(rows):
for j in range(cols):
# Recalculate row kills if we hit a wall or start of row
if j == 0 or grid[i][j-1] == 'W':
row_kills = 0
k = j
while k < cols and grid[i][k] != 'W':
if grid[i][k] == 'E':
row_kills += 1
k += 1
# Recalculate column kills if we hit a wall or start of column
if i == 0 or grid[i-1][j] == 'W':
col_kills[j] = 0
k = i
while k < rows and grid[k][j] != 'W':
if grid[k][j] == 'E':
col_kills[j] += 1
k += 1
# Update result if current cell is empty
if grid[i][j] == '0':
result = max(result, row_kills + col_kills[j])
return result
3. Memory Inefficiency
The Pitfall: Creating a full m x n
auxiliary grid when we only need to track kills for empty cells can be wasteful, especially for large grids with few empty cells.
The Solution: Use a more space-efficient approach that only calculates kills when needed, or use rolling arrays to reduce space complexity from O(m*n) to O(n).
Which technique can we use to find the middle of a linked list?
Recommended Readings
What is Dynamic Programming Prerequisite DFS problems dfs_intro Backtracking problems backtracking Memoization problems memoization_intro Pruning problems backtracking_pruning Dynamic programming is an algorithmic optimization technique that breaks down a complicated problem into smaller overlapping sub problems in a recursive manner and uses solutions to the sub problems to construct a solution
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!