from.count_islands import*from.maze_search import*from.shortest_distance_from_all_buildings import*from.word_ladder import*"""This is a bfs-version of counting-islands problem in dfs section.Given a 2d grid map of '1's (land) and '0's (water),count the number of islands.An island is surrounded by water and is formed byconnecting adjacent lands horizontally or vertically.You may assume all four edges of the grid are all surrounded by water.Example 1:11110110101100000000Answer: 1Example 2:11000110000010000011Answer: 3Example 3:111000110000100001001101001100Answer: 3Example 4:110011001100000001111100Answer: 5"""defcount_islands(grid): row =len(grid) col =len(grid[0]) num_islands =0 visited = [[0] * col for i inrange(row)] directions = [[-1,0], [1,0], [0,-1], [0,1]] queue = []for i inrange(row):for j, num inenumerate(grid[i]):if num ==1and visited[i][j] !=1: visited[i][j] =1 queue.append((i, j))while queue: x, y = queue.pop(0)for k inrange(len(directions)): nx_x = x + directions[k][0] nx_y = y + directions[k][1]if nx_x >=0and nx_y >=0and nx_x < row and nx_y < col:if visited[nx_x][nx_y] !=1and grid[nx_x][nx_y] ==1: queue.append((nx_x, nx_y)) visited[nx_x][nx_y] =1 num_islands +=1return num_islandsfrom collections import deque"""BFS time complexity : O(|E| + |V|)BFS space complexity : O(|E| + |V|)do BFS from (0,0) of the grid and get the minimum number of steps needed to get to the lower right columnonly step on the columns whose value is 1if there is no path, it returns -1Ex 1)If grid is[[1,0,1,1,1,1], [1,0,1,0,1,0], [1,0,1,0,1,1], [1,1,1,0,1,1]], the answer is: 14Ex 2)If grid is[[1,0,0], [0,1,1], [0,1,1]], the answer is: -1"""defmaze_search(maze): BLOCKED, ALLOWED =0,1 UNVISITED, VISITED =0,1 initial_x, initial_y =0,0if maze[initial_x][initial_y] == BLOCKED:return-1 directions = [(0,-1), (0,1), (-1,0), (1,0)] height, width =len(maze),len(maze[0]) target_x, target_y = height -1, width -1 queue =deque([(initial_x, initial_y, 0)]) is_visited = [[UNVISITED for w inrange(width)] for h inrange(height)] is_visited[initial_x][initial_y] = VISITEDwhile queue: x, y, steps = queue.popleft()if x == target_x and y == target_y:return stepsfor dx, dy in directions: new_x = x + dx new_y = y + dyifnot (0<= new_x < height and0<= new_y < width):continueif maze[new_x][new_y] == ALLOWED and is_visited[new_x][new_y] == UNVISITED: queue.append((new_x, new_y, steps +1)) is_visited[new_x][new_y] = VISITEDreturn-1import collections"""do BFS from each building, and decrement all empty place for every building visitwhen grid[i][j] == -b_nums, it means that grid[i][j] are already visited from all b_numsand use dist to record distances from b_nums"""defshortest_distance(grid):ifnot grid ornot grid[0]:return-1 matrix = [[[0,0] for i inrange(len(grid[0]))] for j inrange(len(grid))] count =0# count how many building we have visitedfor i inrange(len(grid)):for j inrange(len(grid[0])):if grid[i][j] ==1:bfs(grid, matrix, i, j, count) count +=1 res =float("inf")for i inrange(len(matrix)):for j inrange(len(matrix[0])):if matrix[i][j][1] == count: res =min(res, matrix[i][j][0])return res if res !=float("inf")else-1defbfs(grid,matrix,i,j,count): q = [(i, j,0)]while q: i, j, step = q.pop(0)for k, l in [(i -1, j), (i +1, j), (i, j -1), (i, j +1)]:# only the position be visited by count times will append to queueif (0<= k <len(grid)and0<= l <len(grid[0])and matrix[k][l][1] == countand grid[k][l] ==0 ): matrix[k][l][0] += step +1 matrix[k][l][1] = count +1 q.append((k, l, step +1))"""Given two words (begin_word and end_word), and a dictionary's word list,find the length of shortest transformation sequencefrom beginWord to endWord, such that:Only one letter can be changed at a timeEach intermediate word must exist in the word listFor example,Given:begin_word = "hit"end_word = "cog"word_list = ["hot","dot","dog","lot","log"]As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",return its length 5.Note:Return -1 if there is no such transformation sequence.All words have the same length.All words contain only lowercase alphabetic characters."""defladder_length(begin_word,end_word,word_list):""" Bidirectional BFS!!! :type begin_word: str :type end_word: str :type word_list: Set[str] :rtype: int """iflen(begin_word)!=len(end_word):return-1# not possibleif begin_word == end_word:return0# when only differ by 1 characterifsum(c1 != c2 for c1, c2 inzip(begin_word, end_word))==1:return1 begin_set =set() end_set =set() begin_set.add(begin_word) end_set.add(end_word) result =2while begin_set and end_set:iflen(begin_set)>len(end_set): begin_set, end_set = end_set, begin_set next_begin_set =set()for word in begin_set:for ladder_word inword_range(word):if ladder_word in end_set:return resultif ladder_word in word_list: next_begin_set.add(ladder_word) word_list.remove(ladder_word) begin_set = next_begin_set result +=1# print(begin_set)# print(result)return-1defword_range(word):for ind inrange(len(word)): temp = word[ind]for c in [chr(x)for x inrange(ord("a"), ord("z") +1)]:if c != temp:yield word[:ind]+ c + word[ind +1:]
BFS Examples
from collections import deque# # 1. We create a search queue and add the starting vertex to it.# 2. We mark the starting vertex as searched.# 3. We loop through the queue.# 4. We get the next person from the queue and then we check if they’re a mango seller.# 5. If they are, we print out that they are a mango seller and return.# 6. If they aren’t, we add all of their neighbors to the search queue.# 7. We mark the person as searched.# 8. We keep looping until the queue is empty.defperson_is_seller(name):return name[-1]=="m"graph ={}graph["you"]= ["alice","bob","claire"]graph["bob"]= ["anuj","peggy"]graph["alice"]= ["peggy"]graph["claire"]= ["thom","jonny"]graph["anuj"]= []graph["peggy"]= []graph["thom"]= []graph["jonny"]= []defsearch(name): search_queue =deque() search_queue += graph[name]# This is how you keep track of which people you've searched before. searched =set()while search_queue: person = search_queue.popleft()# Only search this person if you haven't already searched them.if person notin searched:ifperson_is_seller(person):print(person +" is a mango seller!")returnTrueelse: search_queue += graph[person]# Marks this person as searched searched.add(person)returnFalsesearch("you")