Skip to content

Commit 5006205

Browse files
committed
LEETCODE - Last Day of 2022
1 parent 312b43c commit 5006205

File tree

4 files changed

+343
-0
lines changed

4 files changed

+343
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ This repo contain leetcode solution using DART and GO programming language. Most
173173
- [**1971.* Find if Path Exists in Graph](FindIfPathExistsInGraph/find_if_path_exists_in_graph.dart)
174174
- [**841.** Keys and Rooms](KeysAndRooms/keys_and_rooms.dart)
175175
- [**886.** Possible Bipartition](PossibleBipartition/possible_bipartition.dart)
176+
- [**980.** Unique Paths III](UniquePathsIII/unique_paths_iii.dart)
176177

177178
## Reach me via
178179

UniquePathsIII/unique_paths_iii.dart

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
3+
-* 980. Unique Paths III *-
4+
5+
You are given an m x n integer array grid where grid[i][j] could be:
6+
7+
1 representing the starting square. There is exactly one starting square.
8+
2 representing the ending square. There is exactly one ending square.
9+
0 representing empty squares we can walk over.
10+
-1 representing obstacles that we cannot walk over.
11+
Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once.
12+
13+
14+
15+
Example 1:
16+
17+
18+
Input: grid = [[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
19+
Output: 2
20+
Explanation: We have the following two paths:
21+
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
22+
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)
23+
Example 2:
24+
25+
26+
Input: grid = [[1,0,0,0],[0,0,0,0],[0,0,0,2]]
27+
Output: 4
28+
Explanation: We have the following four paths:
29+
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3)
30+
2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3)
31+
3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3)
32+
4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)
33+
Example 3:
34+
35+
36+
Input: grid = [[0,1],[2,0]]
37+
Output: 0
38+
Explanation: There is no path that walks over every empty square exactly once.
39+
Note that the starting and ending square can be anywhere in the grid.
40+
41+
42+
Constraints:
43+
44+
m == grid.length
45+
n == grid[i].length
46+
1 <= m, n <= 20
47+
1 <= m * n <= 20
48+
-1 <= grid[i][j] <= 2
49+
There is exactly one starting cell and one ending cell.
50+
51+
52+
*/
53+
54+
class A {
55+
int walks = 0;
56+
int res = 0;
57+
static final List<List<int>> values = [
58+
[0, 1],
59+
[0, -1],
60+
[-1, 0],
61+
[1, 0],
62+
];
63+
int uniquePathsIII(List<List<int>> grid) {
64+
res = 0;
65+
walks = 0;
66+
int row = 0, col = 0;
67+
for (int i = 0; i < grid.length; i++) {
68+
for (int j = 0; j < grid[i].length; j++) {
69+
if (grid[i][j] == 0) {
70+
walks++;
71+
} else if (grid[i][j] == 1) {
72+
row = i;
73+
col = j;
74+
}
75+
}
76+
}
77+
dfs(grid, row, col, 0);
78+
return res;
79+
}
80+
81+
void dfs(List<List<int>> grid, int row, int col, int walked) {
82+
if (row < 0 ||
83+
row >= grid.length ||
84+
col < 0 ||
85+
col >= grid[row].length ||
86+
grid[row][col] < 0) {
87+
return;
88+
}
89+
if (grid[row][col] == 2 && walked == walks + 1) {
90+
res++;
91+
return;
92+
}
93+
final int val = grid[row][col];
94+
grid[row][col] = -2;
95+
for (List<int> next in values) {
96+
dfs(grid, row + next[0], col + next[1], walked + 1);
97+
}
98+
grid[row][col] = val;
99+
}
100+
}
101+
102+
class B {
103+
int path = 0;
104+
int sx = 0;
105+
int sy = 0;
106+
int m = 0;
107+
int n = 0;
108+
int zeros = 0;
109+
int uniquePathsIII(List<List<int>> grid) {
110+
m = grid.length;
111+
n = grid[0].length;
112+
List<List<bool>> used =
113+
List.filled(m, false).map((e) => List.filled(n, false)).toList();
114+
115+
for (int i = 0; i < m; i++)
116+
for (int j = 0; j < n; j++) {
117+
if (grid[i][j] == 1) {
118+
sx = i;
119+
sy = j;
120+
} else if (grid[i][j] == 0) zeros++;
121+
}
122+
123+
solve(grid, used, sx, sy, 0);
124+
125+
return path;
126+
}
127+
128+
void solve(
129+
List<List<int>> grid, List<List<bool>> used, int x, int y, int cnt) {
130+
if (grid[x][y] == -1) {
131+
return;
132+
}
133+
if (grid[x][y] == 2) {
134+
if (cnt - 1 == zeros) {
135+
path++;
136+
}
137+
return;
138+
}
139+
used[x][y] = true;
140+
141+
if (y + 1 < n && grid[x][y + 1] != -1 && !used[x][y + 1]) {
142+
solve(grid, used, x, y + 1, cnt + 1);
143+
used[x][y + 1] = false;
144+
}
145+
if (x + 1 < m && grid[x + 1][y] != -1 && !used[x + 1][y]) {
146+
solve(grid, used, x + 1, y, cnt + 1);
147+
used[x + 1][y] = false;
148+
}
149+
if (y - 1 >= 0 && grid[x][y - 1] != -1 && !used[x][y - 1]) {
150+
solve(grid, used, x, y - 1, cnt + 1);
151+
used[x][y - 1] = false;
152+
}
153+
if (x - 1 >= 0 && grid[x - 1][y] != -1 && !used[x - 1][y]) {
154+
solve(grid, used, x - 1, y, cnt + 1);
155+
used[x - 1][y] = false;
156+
}
157+
}
158+
}

UniquePathsIII/unique_paths_iii.go

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package main
2+
3+
func uniquePathsIII(grid [][]int) int {
4+
x, y := findStart(grid)
5+
return helper(grid, x, y)
6+
}
7+
8+
func helper(grid [][]int, x, y int) int {
9+
if grid[x][y] == 2 {
10+
if noZeroes(grid) {
11+
return 1
12+
}
13+
return 0
14+
}
15+
16+
grid[x][y] = 3
17+
ans := 0
18+
19+
if x-1 >= 0 && (grid[x-1][y] == 0 || grid[x-1][y] == 2) {
20+
ans += helper(grid, x-1, y)
21+
}
22+
if y-1 >= 0 && (grid[x][y-1] == 0 || grid[x][y-1] == 2) {
23+
ans += helper(grid, x, y-1)
24+
}
25+
if x+1 < len(grid) && (grid[x+1][y] == 0 || grid[x+1][y] == 2) {
26+
ans += helper(grid, x+1, y)
27+
}
28+
if y+1 < len(grid[0]) && (grid[x][y+1] == 0 || grid[x][y+1] == 2) {
29+
ans += helper(grid, x, y+1)
30+
}
31+
32+
grid[x][y] = 0
33+
34+
return ans
35+
}
36+
37+
func noZeroes(grid [][]int) bool {
38+
for _, x := range grid {
39+
for _, v := range x {
40+
if v == 0 {
41+
return false
42+
}
43+
}
44+
}
45+
46+
return true
47+
}
48+
49+
func findStart(grid [][]int) (int, int) {
50+
for x := 0; x < len(grid); x++ {
51+
for y := 0; y < len(grid[0]); y++ {
52+
if grid[x][y] == 1 {
53+
return x, y
54+
}
55+
}
56+
}
57+
58+
return -1, -1 //error
59+
}

UniquePathsIII/unique_paths_iii.md

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# 🔥 Unique Path - III 🔥 || 2 Solutions || Simple Fast and Easy || with Explanation
2+
3+
## Explanation
4+
5+
The Idea is pretty simple and institutive(in my opinion).
6+
7+
When we are at grid[i,j], we have 4 paths that can be traversed: Up(i-1,j), Down(i+1,j), Left(i,j-1) and Right(i,j+1), except for edges.
8+
9+
Now when I move right from lets say 0,0 to 0,1; at 0,1 i would again make a choice to go left to 0,0 this cannot be allowed, hence we use a boolean matrix to track the path of recursion.
10+
11+
Also, since the starting point could be anywhere, we need to iterate the matrix initially to find the starting i and j, I clubbed counting the number of nodes to visit calculation in this loop. This will help avoid a full boolean matrix scan when we reach "end" point to see if every node has been visited
12+
13+
## Solution - 1 Depth First Search
14+
15+
```dart
16+
class Solution {
17+
int walks = 0;
18+
int res = 0;
19+
static final List<List<int>> values = [
20+
[0, 1],
21+
[0, -1],
22+
[-1, 0],
23+
[1, 0],
24+
];
25+
int uniquePathsIII(List<List<int>> grid) {
26+
res = 0;
27+
walks = 0;
28+
int row = 0, col = 0;
29+
for (int i = 0; i < grid.length; i++) {
30+
for (int j = 0; j < grid[i].length; j++) {
31+
if (grid[i][j] == 0) {
32+
walks++;
33+
} else if (grid[i][j] == 1) {
34+
row = i;
35+
col = j;
36+
}
37+
}
38+
}
39+
depthFirstSearch(grid, row, col, 0);
40+
return res;
41+
}
42+
43+
void depthFirstSearch(List<List<int>> grid, int row, int col, int walked) {
44+
if (row < 0 ||
45+
row >= grid.length ||
46+
col < 0 ||
47+
col >= grid[row].length ||
48+
grid[row][col] < 0) {
49+
return;
50+
}
51+
if (grid[row][col] == 2 && walked == walks + 1) {
52+
res++;
53+
return;
54+
}
55+
final int val = grid[row][col];
56+
grid[row][col] = -2;
57+
for (List<int> next in values) {
58+
dfs(grid, row + next[0], col + next[1], walked + 1);
59+
}
60+
grid[row][col] = val;
61+
}
62+
}
63+
```
64+
65+
## Solution - 2 Recursion
66+
67+
```dart
68+
class Solution {
69+
int path = 0;
70+
int sx = 0;
71+
int sy = 0;
72+
int m = 0;
73+
int n = 0;
74+
int zeros = 0;
75+
int uniquePathsIII(List<List<int>> grid) {
76+
m = grid.length;
77+
n = grid[0].length;
78+
List<List<bool>> used =
79+
List.filled(m, false).map((e) => List.filled(n, false)).toList();
80+
81+
for (int i = 0; i < m; i++)
82+
for (int j = 0; j < n; j++) {
83+
if (grid[i][j] == 1) {
84+
sx = i;
85+
sy = j;
86+
} else if (grid[i][j] == 0) zeros++;
87+
}
88+
89+
solve(grid, used, sx, sy, 0);
90+
91+
return path;
92+
}
93+
94+
void solve(
95+
List<List<int>> grid, List<List<bool>> used, int x, int y, int cnt) {
96+
if (grid[x][y] == -1) {
97+
return;
98+
}
99+
if (grid[x][y] == 2) {
100+
if (cnt - 1 == zeros) {
101+
path++;
102+
}
103+
return;
104+
}
105+
used[x][y] = true;
106+
107+
if (y + 1 < n && grid[x][y + 1] != -1 && !used[x][y + 1]) {
108+
solve(grid, used, x, y + 1, cnt + 1);
109+
used[x][y + 1] = false;
110+
}
111+
if (x + 1 < m && grid[x + 1][y] != -1 && !used[x + 1][y]) {
112+
solve(grid, used, x + 1, y, cnt + 1);
113+
used[x + 1][y] = false;
114+
}
115+
if (y - 1 >= 0 && grid[x][y - 1] != -1 && !used[x][y - 1]) {
116+
solve(grid, used, x, y - 1, cnt + 1);
117+
used[x][y - 1] = false;
118+
}
119+
if (x - 1 >= 0 && grid[x - 1][y] != -1 && !used[x - 1][y]) {
120+
solve(grid, used, x - 1, y, cnt + 1);
121+
used[x - 1][y] = false;
122+
}
123+
}
124+
}
125+
```

0 commit comments

Comments
 (0)