Switch to deque for DFS implementation

Signed-off-by: Aadit Kamat <aadit.k12@gmail.com>
pull/137/head
Aadit Kamat 6 years ago
parent 0d05821d76
commit 54defd7b24

@ -32,34 +32,36 @@ In coding interviews, graphs are commonly represented as 2-D matrices where cell
A simple template for doing depth-first searches on a matrix goes like this: A simple template for doing depth-first searches on a matrix goes like this:
```py ```py
def dfs(matrix, method): from collections import deque
def dfs(matrix):
# check for an empty graph
if len(matrix) == 0:
return []
rows, cols = len(matrix), len(matrix[0]) rows, cols = len(matrix), len(matrix[0])
visited = set() visited = set()
directions = ((0, 1), (0, -1), (1, 0), (-1, 0)) directions = ((0, 1), (0, -1), (1, 0), (-1, 0))
# Depends upon the question: many grid questions have blocked cells. # Uses short circuiting to check whether current position is within the
# This implementation assumes 0s represent valid and 1s represent invalid # boundary and has not been visited before checking if it is valid
def is_valid(i, j):
return matrix[i][j] == 0
# Uses short circuiting to check whether current position is within the boundary
# and has not been visited before checking if it is valid
def pass_all_conditions(i, j): def pass_all_conditions(i, j):
return i in range(rows) and j in range(cols) and (i, j) not in visited \ return i in range(rows) and j in range(cols) and (i, j) not in visited
and is_valid((i, j))
def traverse(i, j): def traverse(i, j):
if not pass_all_conditions(i, j): stack = deque([(i, j)])
return while stack:
visited.add((i, j)) curr_i, curr_j = stack.pop()
# Traverse neighbors if pass_all_conditions(curr_i, curr_j):
for direction in directions: visited.add((curr_i, curr_j))
next_i, next_j = i + direction[0], j + direction[1] # Traverse neighbors
for direction in directions:
next_i, next_j = curr_i + direction[0], curr_j + direction[1]
stack.append((next_i, next_j))
for i in range(rows): for i in range(rows):
for j in range(cols): for j in range(cols):
dfs(i, j) traverse(i, j)
``` ```
@ -68,32 +70,35 @@ Another similar template for doing breadth first searches on the matrix goes lik
```py ```py
from collections import deque from collections import deque
def bfs(matrix, method):
def add_neighbours(queue, current_point): def bfs(matrix):
visited.add(current_point) # check for an empty graph
for direction in directions: if len(matrix) == 0:
new_x, new_y = current_point[0] + direction[0], current_point[1] + direction[1] return []
queue.append((new_x, new_y)) rows, cols = len(matrix), len(matrix[0])
visited = set()
# Depends upon the question: many grid questions have blocked cells. directions = ((0, 1), (0, -1), (1, 0), (-1, 0))
# This implementation assumes 0s represent valid and 1s represent invalid
def is_valid(i, j): # Uses short circuiting to check whether current position is within the
return matrix[i][j] == 0 # boundary and has not been visited before checking if it is valid
def pass_all_conditions(i, j):
# Uses short circuiting to check whether current position is within the boundary return i in range(rows) and j in range(cols) and (i, j) not in visited
# and has not been visited before checking if it is valid
def pass_all_conditions(current_point): def traverse(i, j):
return i in range(rows) and j in range(cols) and current_point not in visited \ queue = deque([(i, j)])
and is_valid(current_point) while queue:
curr_i, curr_j = queue.pop()
# Handle disjointed graphs if pass_all_conditions(curr_i, curr_j):
for x in range(rows): visited.add((curr_i, curr_j))
for y in range(cols): # Traverse neighbors
queue = deque([(i, j)]) for direction in directions:
while store: next_i, next_j = curr_i + direction[0], curr_j + direction[1]
current_point = queue.popleft() queue.append((next_i, next_j))
if pass_all_conditions(current_point):
add_neighbours(store, current_point) for i in range(rows):
for j in range(cols):
traverse(i, j)
``` ```
> NOTE: While DFS is implemented using recursion in this sample, it could also be implemented iteratively similar to BFS. The key difference between the algorithms lies in the underlying data structure (BFS uses a queue while DFS uses a stack). The `deque` class in Python can function as both a stack and a queue > NOTE: While DFS is implemented using recursion in this sample, it could also be implemented iteratively similar to BFS. The key difference between the algorithms lies in the underlying data structure (BFS uses a queue while DFS uses a stack). The `deque` class in Python can function as both a stack and a queue

Loading…
Cancel
Save