2257. Count Unguarded Cells in the Grid
내 코드
바로 그냥 중복 방문했다가 TLE 이후에 마땅히 좋은 아이디어가 없었다.
- ms, MB
class Solution {
public:
int countUnguarded(int m, int n, vector<vector<int>>& guards, vector<vector<int>>& walls) {
vector board(m, vector(n, 0));
for(auto wall : walls) {
int x = wall[0], y = wall[1];
board[x][y] = 2; // wall
}
for(auto guard : guards) {
int guardX = guard[0], guardY = guard[1];
board[guardX][guardY] = 1;
for(int d{};d<4;++d) {
int x = guardX, y = guardY;
while(1) {
int nx = x + "0211"[d] - '1', ny = y + "1102"[d] - '1';
if(nx < 0 || nx >= m || ny < 0 || ny >= n) break;
if(board[nx][ny] == 2) break;
x = nx, y = ny;
board[nx][ny] = 1;
}
}
}
int answer{};
for(auto row : board) {
for(auto col : row) {
if(!col) ++answer;
}
}
return answer;
}
};
밑에 Approach 1 참고해서..
- guard를 미리 순회해서 채워 넣는 경우 시간 내에 통과 가능..!
- 81ms, 186.49MB
class Solution {
public:
int countUnguarded(int m, int n, vector<vector<int>>& guards, vector<vector<int>>& walls) {
vector board(m, vector(n, 0));
// guard를 초기에 한 번 더 미리 채워 넣기(중복 방문 방지)
for(auto& guard : guards) {
int guardX = guard[0], guardY = guard[1];
board[guardX][guardY] = 1; // guard
}
for(auto& wall : walls) {
int x = wall[0], y = wall[1];
board[x][y] = 2; // wall
}
for(auto& guard : guards) {
for(int d{};d<4;++d) {
int x = guard[0], y = guard[1];
while(1) {
int nx = x + "0211"[d] - '1', ny = y + "1102"[d] - '1';
if(nx < 0 || nx >= m || ny < 0 || ny >= n) break;
if(board[nx][ny] == 2) break; // wall
if(board[nx][ny] == 1) break; // guard
x = nx, y = ny;
board[nx][ny] = 3;
}
}
}
int answer{};
for(auto row : board) {
for(auto col : row) {
if(!col) ++answer;
}
}
return answer;
}
};
Solution
Approach 1: Iterative Simulation
- 63ms, 172.17MB
- Complexity
- Let
mbe the number of rows,nthe number of columns,gbe the number of guards in theguardslist, andwbe the number of walls in thewallslist. - Time Complexity:
- Space Complexity:
- Let
class Solution {
public:
const int UNGUARDED = 0;
const int GUARDED = 1;
const int GUARD = 2;
const int WALL = 3;
void markguarded(int row, int col, vector<vector<int>>& grid) {
// Traverse upwards
for (int r = row - 1; r >= 0; r--) {
if (grid[r][col] == WALL || grid[r][col] == GUARD) break;
grid[r][col] = GUARDED;
}
// Traverse downwards
for (int r = row + 1; r < grid.size(); r++) {
if (grid[r][col] == WALL || grid[r][col] == GUARD) break;
grid[r][col] = GUARDED;
}
// Traverse leftwards
for (int c = col - 1; c >= 0; c--) {
if (grid[row][c] == WALL || grid[row][c] == GUARD) break;
grid[row][c] = GUARDED;
}
// Traverse rightwards
for (int c = col + 1; c < grid[row].size(); c++) {
if (grid[row][c] == WALL || grid[row][c] == GUARD) break;
grid[row][c] = GUARDED;
}
}
int countUnguarded(int m, int n, vector<vector<int>>& guards,
vector<vector<int>>& walls) {
vector<vector<int>> grid(m, vector<int>(n, UNGUARDED));
// Mark guards' positions
for (const auto& guard : guards) {
grid[guard[0]][guard[1]] = GUARD;
}
// Mark walls' positions
for (const auto& wall : walls) {
grid[wall[0]][wall[1]] = WALL;
}
// Mark cells as guarded by traversing from each guard
for (const auto& guard : guards) {
markguarded(guard[0], guard[1], grid);
}
// Count unguarded cells
int count = 0;
for (const auto& row : grid) {
for (const auto& cell : row) {
if (cell == UNGUARDED) count++;
}
}
return count;
}
};
Approach 2: Recursive Way
- 60ms, 172.24MB
- Complexity
- Let
mbe the number of rows,nthe number of columns,gbe the number of guards in theguardslist, andwbe the number of walls in thewallslist. - Time Complexity:
- Space Complexity:
- Let
class Solution {
public:
const int UNGUARDED = 0;
const int GUARDED = 1;
const int GUARD = 2;
const int WALL = 3;
void recurse(int row, int col, vector<vector<int>>& grid, char direction) {
if (row < 0 || row >= grid.size() || col < 0 ||
col >= grid[row].size() || grid[row][col] == GUARD ||
grid[row][col] == WALL) {
return;
}
grid[row][col] = GUARDED; // Mark cell as guarded
if (direction == 'U') recurse(row - 1, col, grid, 'U'); // Up
if (direction == 'D') recurse(row + 1, col, grid, 'D'); // Down
if (direction == 'L') recurse(row, col - 1, grid, 'L'); // Left
if (direction == 'R') recurse(row, col + 1, grid, 'R'); // Right
}
int countUnguarded(int m, int n, vector<vector<int>>& guards,
vector<vector<int>>& walls) {
vector<vector<int>> grid(m, vector<int>(n, UNGUARDED));
// Mark guards' positions
for (const auto& guard : guards) {
grid[guard[0]][guard[1]] = GUARD;
}
// Mark walls' positions
for (const auto& wall : walls) {
grid[wall[0]][wall[1]] = WALL;
}
// Mark cells as guarded by traversing from each guard
for (const auto& guard : guards) {
recurse(guard[0] - 1, guard[1], grid, 'U'); // Up
recurse(guard[0] + 1, guard[1], grid, 'D'); // Down
recurse(guard[0], guard[1] - 1, grid, 'L'); // Left
recurse(guard[0], guard[1] + 1, grid, 'R'); // Right
}
// Count unguarded cells
int count = 0;
for (const auto& row : grid) {
for (const auto& cell : row) {
if (cell == UNGUARDED) count++;
}
}
return count;
}
};