Skip to content

Commit

Permalink
feat(C++): Add 1293
Browse files Browse the repository at this point in the history
Mad amount of edge cases that I failed to consider...
  • Loading branch information
euchangxian committed Oct 31, 2024
1 parent 04b363f commit 2dafd5a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
76 changes: 76 additions & 0 deletions C++/1293-ShortestPathInAGridWithObstaclesElimination/Solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <array>
#include <cstddef>
#include <queue>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;
class Solution {
private:
// Need to consider all 4 directions instead of just right and bottom. This
// is to deal with the situation where the obstacle blocks right/bottom, and
// the only path is left/top
static constexpr std::array<std::pair<int, int>, 4> directions{
{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}};

public:
int shortestPath(vector<vector<int>>& grid, int k) {
// grid[i][j] = 0 (empty) | 1 (obstacle)
// Move in cardinal directions to an empty cell.
// k is the number of obstacles that can be eliminated.
//
// Start (0, 0), Goal (m-1, n-1)
// Intuition is just BFS with an extra state to represent the number of
// obstacles break remaining.
const size_t rows = grid.size();
const size_t cols = grid[0].size();
if (k >= rows + cols - 2) {
// manhattan dist between (0, 0) and (rows-1, cols-1)
// This optimization is necessary to avoid unnecessary traversal if we
// can determine that we can just break through all obstacles.
return rows + cols - 2;
}

std::queue<std::tuple<int, int, int>> frontier;
std::vector<std::vector<std::vector<bool>>> seen(
rows,
std::vector<std::vector<bool>>(cols, std::vector<bool>(k + 1, false)));
frontier.emplace(0, 0, k);
seen[0][0][k] = true;

int steps = 0;
while (!frontier.empty()) {
int size = frontier.size();
while (size--) {
const auto [r, c, breaks] = frontier.front();
frontier.pop();

if (r == rows - 1 && c == cols - 1) {
return steps;
}

for (const auto& [dr, dc] : directions) {
const int nr = r + dr;
const int nc = c + dc;

if (nr < 0 || nc < 0 || nr >= rows || nc >= cols) {
continue;
}

int newBreaks = breaks - grid[nr][nc];
if ((grid[nr][nc] == 1 && breaks <= 0) || seen[nr][nc][newBreaks]) {
// note we check newBreaks AFTER checkin of breaks <= 0.
// Avoid negative indexing.
continue;
}

frontier.emplace(nr, nc, newBreaks);
seen[nr][nc][newBreaks] = true;
}
}
++steps;
}
return -1;
}
};
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ Now solving in C++. Like it.
| 1255 | MaximumScoreWordsFormedByLetters | [![C++](assets/c++.svg)](C++/1255-MaximumScoreWordsFormedByLetters/Solution.cpp) |
| 1257 | SmallestCommonRegion | [![C++](assets/c++.svg)](C++/1257-SmallestCommonRegion/Solution.cpp) |
| 1277 | CountSquareSubmatricesWithOnes | [![C++](assets/c++.svg)](C++/1277-CountSquareSubmatricesWithOnes/Solution.cpp) |
| 1293 | ShortestPathInAGridWithObstaclesElimination | [![C++](assets/c++.svg)](C++/1293-ShortestPathInAGridWithObstaclesElimination/Solution.cpp) |
| 1310 | XORQueriesOfASubarray | [![C++](assets/c++.svg)](C++/1310-XORQueriesOfASubarray/Solution.cpp) |
| 1317 | ConvertIntegerToTheSumOfTwoNoZeroIntegers | [![C++](assets/c++.svg)](C++/1317-ConvertIntegerToTheSumOfTwoNoZeroIntegers/Solution.cpp) |
| 1323 | Maximum69Number | [![C++](assets/c++.svg)](C++/1323-Maximum69Number/Solution.cpp) |
Expand Down

0 comments on commit 2dafd5a

Please sign in to comment.