Skip to content

Commit b6031e5

Browse files
committed
Added bi-directional to 1091.
1 parent 61fbee1 commit b6031e5

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

leetcode/medium/1091_shortest_path_in_binary_matrix.md

+46-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# 1091. Shortest Path in Binary Matrix
22

33
## BFS Solution
4-
- Runtime: O(N)
4+
- Run-time: O(N)
55
- Space: O(N)
66
- N = Number of elements in grid
77

@@ -33,29 +33,70 @@ class Solution:
3333
bfs_queue.append((_x, _y))
3434
grid[_x][_y] = -1
3535
return -1
36-
36+
3737
def get_neighbors(self, grid, x, y):
3838
axises = [(1,0),(0,1),(0,-1),(-1,0),(-1,-1),(1,-1),(-1,1),(1,1)]
3939
for _x, _y in axises:
4040
_x += x
4141
_y += y
4242
if self.within_bounds(_x, _y, grid) and grid[_x][_y] == 0:
4343
yield (_x, _y)
44-
44+
4545
def within_bounds(self, x, y, grid):
4646
return x >= 0 and x < len(grid) and y >= 0 and y < len(grid[0])
4747
```
4848

4949
## Bi-directional BFS Best Solution
50-
- Runtime: O(N)
50+
- Run-time: O(N)
5151
- Space: O(N)
5252
- N = Number of elements in grid
5353

5454
We can further improve the run-time of the BFS by using a bi-directional BFS.
5555
If you imagine a circle, every time you expand the circle, the number of neighbors being visited almost doubles.
5656
Now if you used two circles and expanded them both simultaneously, when they touch, it would have visited less neighbors compared to using one circle.
57-
This increases the run-time even more for some inputs, worst case, is the same as the first BFS solution.
57+
This decreases the run-time for some inputs, worst case, is the same as the first BFS solution.
5858

5959
```
60+
from collections import deque
61+
62+
class Solution(object):
63+
def shortestPathBinaryMatrix(self, grid):
64+
65+
def get_neighbors(row_idx, col_idx):
66+
dirs = [(0,1),(1,0),(0,-1),(-1,0),(1,1),(-1,-1),(-1,1),(1,-1)]
67+
for r, c in dirs:
68+
r += row_idx
69+
c += col_idx
70+
if 0 <= r < len(grid) and 0 <= c < len(grid[0]):
71+
yield (r, c)
6072
73+
def bfs_once(queue, our_num, other_num):
74+
for _ in range(len(queue)):
75+
node = queue.pop()
76+
for x, y in get_neighbors(node[0], node[1]):
77+
if grid[x][y] == other_num: # intersection
78+
return True
79+
elif grid[x][y] == 0:
80+
grid[x][y] = our_num
81+
queue.appendleft((x, y))
82+
return False
83+
84+
if not grid or len(grid) == 0 or len(grid[0]) == 0: # is grid empty?
85+
return -1
86+
elif len(grid) == 1 and len(grid[0]) == 1: # does grid only contain one element?
87+
return 1
88+
elif grid[0][0] == 1 or grid[-1][-1] == 1: # are start or end blocked?
89+
return -1
90+
queue1 = deque([(0, 0)])
91+
queue2 = deque([(len(grid)-1, len(grid[0])-1)])
92+
grid[0][0], grid[-1][-1] = 2, 3 # numbers represent two visited sets
93+
n_moves = 2
94+
while queue1 and queue2:
95+
if bfs_once(queue1, 2, 3):
96+
return n_moves
97+
n_moves += 1
98+
if bfs_once(queue2, 3, 2):
99+
return n_moves
100+
n_moves += 1
101+
return -1
61102
```

leetcode/medium/348_design_tic-tac-toe.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
## Solution
44

5-
- Run-time: O(1)
6-
- Space: O(N)
5+
- Runtime: O(1)
6+
- Space: O(1)
77
- N = Given N
88

9+
This is a fair production code quality example.
910
Make sure when you code, you break down your methods else you may fail this question.
1011

11-
To achieve O(N) run-time, we can use a summation system for each row, column and the two diagonals.
12+
To achieve O(1) run-time, we can use a summation system for each row, column and the two diagonals.
1213
Player 1 will increment by 1 and player 2 will decrement by 1.
1314
This means that for any given row, column or diagonal, if either equal N or -N, there is a straight line for the same player.
1415

0 commit comments

Comments
 (0)