forked from shuboc/LeetCode-2
-
Notifications
You must be signed in to change notification settings - Fork 1
/
unique-paths-iii.cpp
73 lines (66 loc) · 2.23 KB
/
unique-paths-iii.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Time: O(m * n * 2^(m * n))
// Space: O(m * n * 2^(m * n))
class Solution {
private:
template <typename T>
struct PairHash {
size_t operator()(const pair<T, T>& p) const {
size_t seed = 0;
seed ^= std::hash<T>{}(p.first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
seed ^= std::hash<T>{}(p.second) + 0x9e3779b9 + (seed<<6) + (seed>>2);
return seed;
}
};
using Lookup = unordered_map<pair<int, int>, int, PairHash<int>>;
public:
int uniquePathsIII(vector<vector<int>>& grid) {
int todo = 0;
pair<int, int> src, dst;
for (int r = 0; r < grid.size(); ++r) {
for (int c = 0; c < grid[0].size(); ++c) {
if (grid[r][c] % 2 == 0) {
todo |= index(grid, r, c);
}
if (grid[r][c] == 1) {
src = make_pair(r, c);
} else if (grid[r][c] == 2) {
dst = make_pair(r, c);
}
}
}
Lookup lookup;
return dp(grid, src, dst, todo, &lookup);
}
private:
int dp(const vector<vector<int>>& grid,
const pair<int, int>& src,
const pair<int, int>& dst,
int todo,
Lookup *lookup) {
if (src == dst) {
return (todo == 0);
}
const auto& key = make_pair(index(grid, src.first, src.second), todo);
if (lookup->count(key)) {
return (*lookup)[key];
}
static const vector<pair<int, int>> directions =
{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int result = 0;
for (const auto& d : directions) {
int r = src.first + d.first, c = src.second + d.second;
if (0 <= r && r < grid.size() &&
0 <= c && c < grid[0].size() &&
grid[r][c] % 2 == 0 &&
todo & index(grid, r, c)) {
result += dp(grid, make_pair(r, c), dst,
todo ^ index(grid, r, c), lookup);
}
}
(*lookup)[key] = result;
return (*lookup)[key];
}
int index(const vector<vector<int>>& grid, int r, int c) {
return 1 << (r * grid[0].size() + c);
}
};