1.DFS (depth first search) and BFS (breadth first search) collection.
2. The main difference between the two is that the former maintains a stack data structure, so the recursive method can usually be used; The latter maintains the data structure of a queue, usually using the method of circular iteration.
3. At the same time, if the former is implemented by recursion, only the form of recursion and the conditions for ending recursion need to be considered. The computer maintains the stack itself, which is more convenient and easy to understand. The latter needs to write its own iteration to maintain the queue, which is relatively complex to start
4. If you are familiar with backtracking and recursion, DFS is easy to use, and there will be little explanation below
Color fill (simple)
- Idea: DFS, pay attention to boundary conditions and special cases, and then search (fill color) in four directions up, down, left and right
var floodFill = function(image, sr, sc, newColor) { let begin = image[sr][sc] // Special attention if (begin === newColor) return image let srlen = image.length - 1, sclen = image[0].length - 1 let dfs = (image, sr, sc, newColor) => { // Focus on boundary conditions if (sr < 0 || sc < 0 || sr > srlen || sc > sclen) return if (image[sr][sc] === begin) { image[sr][sc] = newColor } else { return } dfs(image, sr - 1, sc, newColor) // lower dfs(image, sr + 1, sc, newColor) // upper dfs(image, sr, sc - 1, newColor) // Left dfs(image, sr, sc + 1, newColor) // right } dfs(image, sr, sc, newColor) return image };
Number of islands (medium)
- Idea: cycle through the grid array. As long as the current value is 1, add one to the count, and then perform DFS search in four directions up, down, left and right until it meets zero, and the place it passes each time should become zero to prevent repeated search from falling into an endless loop (such as searching from left to right, and from right to left, and so on)
var numIslands = function(grid) { if (!grid.length) return 0 let nr = grid.length let nc = grid[0].length let sum = 0 let dfs = (grid, r, c) => { if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] === '0') return grid[r][c] = '0' // The searched place is assigned to zero dfs(grid, r - 1, c) // lower dfs(grid, r + 1, c) // upper dfs(grid, r, c - 1) // Left dfs(grid, r, c + 1) // right } // Traversal array for (let i = 0; i < nr; i++) { for (let j = 0; j < nc; j++) { if (grid[i][j] === '1') { sum++ dfs(grid, i, j) } } } return sum };
Water area size (medium)
- Idea: compared with the previous question, it has four more search directions - diagonal, but there is no essential difference. It can be done as long as you search several more directions
var pondSizes = function(land) { if (!land.length) return [] let res = [], size = 0 let nr = land.length let nc = land[0].length let dfs = (land, r, c) => { if (r < 0 || c < 0 || r >= nr || c >= nc || land[r][c] !== 0) return land[r][c] = -1 size++ // Search in eight directions dfs(land, r - 1, c) dfs(land, r - 1, c - 1) dfs(land, r - 1, c + 1) dfs(land, r, c - 1) dfs(land, r, c + 1) dfs(land, r + 1, c) dfs(land, r + 1, c - 1) dfs(land, r + 1, c + 1) return size } for (let i = 0; i < nr; i++) { for (let j = 0; j < nc; j++) { if (land[i][j] === 0) { size = 0 dfs(land, i, j) if (size !== 0) res.push(size) } } } return res.sort() };
Open keyboard lock (medium)
- thinking
- BFS. The code and ideas are complex. Look at the form of the topic, you can think of using a queue, because the operation is carried out in sequence, and the next rotation can only be carried out after one rotation. The difficulty of this problem is that it is easy to fall into a dead end - thinking about using code to write rotation operation and iteration together, and the two are carried out at the same time. If you think about it carefully, you will find that it is very hybrid, or almost impossible to achieve, because there are many situations after one rotation. So we need to turn the rotation operation into a function, and return the value to the array with various conditions. We can call the function in every iteration and traverse the result.
- The rotation function and can directly see the code comments. Here we mainly talk about the idea of iteration. Maintain a queue, first store the initial state of 0000, then enter the total cycle (once for each total cycle, the number of steps plus one), then traverse and take out the states in the queue, and rotate each state. The results are stored in the array, and then the results in the rotating array are stored in the queue according to the sequence (at the same time, judge whether they meet the requirements, store them in the queue if they do not meet the requirements, and return the results if they meet the requirements), and then iterate over each result when entering the total cycle
var openLock = function(deadends, target) { if (target === '0000') return 0 if (deadends.includes('0000')) return -1 // The result of enumeration rotation is a string, which requires additional processing const go = (x) => { // Forward rotation return x === '9' ? '0' : (parseInt(x) + 1) + '' } const back = (x) => { // reversal return x === '0' ? '9' : (parseInt(x) - 1) + '' } const get = (status) => { const res = [] const arr = Array.from(status) // Only four digits for (let i = 0; i < 4; i++) { const num = arr[i] // Save current traversal number arr[i] = go(num) res.push(arr.join('')) // Deposit forward transfer result arr[i] = back(num) res.push(arr.join('')) // Save reversal result arr[i] = num // Restore current traversal number } return res // Returns all results of one rotation } // BFS let step = 0 let dead = new Set(deadends) const queue = [] queue.push('0000') let seed = new Set() seed.add('0000') while (queue.length) { step++ const len = queue.length for (let i = 0; i < len; i++) { // Take out multiple results after the last rotation in sequence let status = queue.shift() // Traverse the various cases of rotation once for (let next of get(status)) { // Judge whether it meets the requirements, store it in the queue if it does not meet the requirements, and return the results if it meets the requirements if (!seed.has(next) && !dead.has(next)) { if (next === target) { return step } else { queue.push(next) seed.add(next) } } } } } return -1 };
Word search (medium)
- Idea: DFS, the efficiency after submission is extremely low and outrageous. Traverse each element of the array, and then search up, down, left and right. General, not much explanation
var exist = function(board, word) { let len = word.length let nr = board.length let nc = board[0].length let isTrue = false let dfs = (board, r, c, sub) => { if (r < 0|| c < 0 || r >= nr || c >= nc || sub.length > len || board[r][c] === '1') return sub += board[r][c] if (sub === word) isTrue = true let str = board[r][c] board[r][c] = '1' dfs(board, r - 1, c, sub) dfs(board, r + 1, c, sub) dfs(board, r, c - 1, sub) dfs(board, r, c + 1, sub) board[r][c] = str } for (let i = 0; i < nr; i++) { for (let j = 0; j < nc; j++) { if (board[i][j] === word[0]) { dfs(board, i, j, '') } } } return isTrue };
Curriculum (medium)
- Idea: BFS, the efficiency after submission is extremely low and outrageous. This problem involves topological sorting. If you understand topological sorting, you will understand it very well
var canFinish = function(numCourses, prerequisites) { let pic = new Array(numCourses) let len = prerequisites.length let queue = [], sum = 0 for (let i = 0; i < numCourses; i++) { pic[i] = [] } // Store the corresponding relationship of course order to form a topology for (let i = 0; i < len; i++) { let [back, pre] = prerequisites[i] pic[back].push(pre) } // First, the nodes with zero penetration are stored in the queue for (let i = 0; i < numCourses; i++) { if (pic[i].length === 0) queue.push(i) } // Check whether there is a ring in the topology. If there is no ring, it returns true while (queue.length) { let mid = queue.shift() for (let i = 0; i < numCourses; i++) { let cur = pic[i] let index = cur.indexOf(mid) if (index === -1) continue cur.splice(index, 1) if (cur.length === 0) queue.push(i) } sum++ } return sum === numCourses };
If you think it's helpful to you, give it a compliment~
Anyway, posting doesn't make money. Make friends~
If you need to reprint, please indicate the source foolBirdd