LeetCode: Escape a Large Maze Posted on August 5, 2019July 26, 2020 by braindenny Escape a Large Maze Similar Problems: CheatSheet: Leetcode For Code Interview CheatSheet: Common Code Problems & Follow-ups Tag: #graph, #game, #dfs, #bfs In a 1 million by 1 million grid, the coordinates of each grid square are (x, y) with 0 <= x, y < 10^6. We start at the source square and want to reach the target square. Each move, we can walk to a 4-directionally adjacent square in the grid that isn’t in the given list of blocked squares. Return true if and only if it is possible to reach the target square through a sequence of moves. Example 1: Input: blocked = [[0,1],[1,0]], source = [0,0], target = [0,2] Output: false Explanation: The target square is inaccessible starting from the source square, because we can't walk outside the grid. Example 2: Input: blocked = [], source = [0,0], target = [999999,999999] Output: true Explanation: Because there are no blocked cells, it's possible to reach the target square. Note: 0 <= blocked.length <= 200 blocked[i].length == 2 0 <= blocked[i][j] < 10^6 source.length = target.length = 2 0 <= source[i][j], target[i][j] < 10^6 source != target Github: code.dennyzhang.com Credits To: leetcode.com Leave me comments, if you have better ways to solve. Solution: DFS // Basic Ideas: DFS // // Key Observations: // For a cell, if four directions are blocked, this cell is blocked // If there is a blocked loop around source or target, we may not be able to find a route // The maximum are of blocked region is limited, given at 200 nodes in blocked list // // Notice: what if both source and target are inside one blocked loop? // // Complexity: Time ?, Space ? import "math" type MyNode struct { i, j int } func dfs(i int, j int, target []int, blocks map[MyNode]bool, seen map[MyNode]bool) bool { bound := int(math.Pow(10, 6)) // position is valid if i<0 || i>=bound || j<0 || j>=bound { return false } node := MyNode{i:i, j:j} if blocks[node] || seen[node] { return false } // find target if i == target[0] && j == target[1] { return true } // move out of the blocked region if len(seen) >= 20000 { return true } seen[node] = true return dfs(i+1, j, target, blocks, seen) || dfs(i-1, j, target, blocks, seen) || dfs(i, j+1, target, blocks, seen) || dfs(i, j-1, target, blocks, seen) } func isEscapePossible(blocked [][]int, source []int, target []int) bool { blocks := map[MyNode]bool{} for _, node := range blocked { blocks[MyNode{i:node[0], j:node[1]}] = true } if blocks[MyNode{i:source[0], j:source[1]}] || blocks[MyNode{i:target[0], j:target[1]}] { return false } return dfs(source[0], source[1], target, blocks, map[MyNode]bool{}) && dfs(target[0], target[1], source, blocks, map[MyNode]bool{}) } Solution: BFS // https://code.dennyzhang.com/escape-a-large-maze // Basic Ideas: BFS // // Key Observations: // For a cell, if four directions are blocked, this cell is blocked // If there is a blocked loop around source or target, we may not be able to find a route // The maximum are of blocked region is limited, given at 200 nodes in blocked list // // Notice: what if both source and target are inside one blocked loop? // // Complexity: Time ?, Space ? import "math" type MyNode struct { i, j int } func bfs(source []int, target []int, blocks map[MyNode]bool, maxRegion int) bool { bound := int(math.Pow(10, 6)) seen := map[MyNode]bool{} seen[MyNode{source[0], source[1]}] = true queue := [][]int{source} for len(queue) > 0 { l := [][]int{} for _, node := range queue { // get nexts for _, offset := range [][]int{[]int{1, 0}, []int{-1, 0}, []int{0, 1},[]int{0, -1}} { i2, j2 := node[0]+offset[0], node[1]+offset[1] if i2<0 || i2>=bound || j2<0 || j2>=bound { continue } node2 := MyNode{i:i2, j:j2} if blocks[node2] || seen[node2] { continue } if i2==target[0] && j2==target[1] { return true } seen[node2] = true l = append(l, []int{i2, j2}) } } queue = l if len(seen) > maxRegion { return true } } return false } func isEscapePossible(blocked [][]int, source []int, target []int) bool { blocks := map[MyNode]bool{} for _, node := range blocked { blocks[MyNode{i:node[0], j:node[1]}] = true } if blocks[MyNode{i:source[0], j:source[1]}] || blocks[MyNode{i:target[0], j:target[1]}] { return false } maxRegion := (len(blocked)*(len(blocked)-1))/2 return bfs(source, target, blocks, maxRegion) && bfs(target, source, blocks, maxRegion) } Post Views: 0 Post navigation Series: Coloring graph nodes Problems & Follow-upSeries: Change cells of graph Problems & Follow-up Leave a Reply Cancel replyYour email address will not be published.Comment Name Email Website