[关闭]
@Yano 2019-09-20T10:49:47.000000Z 字数 8643 阅读 3933

LeetCode Depth First Search 题目汇总

LeetCode


公众号

coding 笔记、点滴记录,以后的文章也会同步到公众号(Coding Insight)中,希望大家关注^_^

https://github.com/LjyYano/Thinking_in_Java_MindMapping

130 Surrounded Regions

https://leetcode.com/problems/surrounded-regions/

题目描述

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

For example,

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

代码

  1. class Solution {
  2. public void solve(char[][] board) {
  3. for (int i = 0; i < board.length; i++) {
  4. for (int j = 0; j < board[0].length; j++) {
  5. if ((i == 0 || i == board.length - 1 || j == 0 || j == board[0].length - 1) && board[i][j] == 'O') {
  6. dfs(i, j, board);
  7. }
  8. }
  9. }
  10. for (int i = 0; i < board.length; i++) {
  11. for (int j = 0; j < board[0].length; j++) {
  12. if (board[i][j] == '$') {
  13. board[i][j] = 'O';
  14. } else if (board[i][j] == 'O') {
  15. board[i][j] = 'X';
  16. }
  17. }
  18. }
  19. }
  20. private void dfs(int i, int j, char[][] board) {
  21. if (board[i][j] == 'O') {
  22. board[i][j] = '$';
  23. if (i > 0 && board[i - 1][j] == 'O') {
  24. dfs(i - 1, j, board);
  25. }
  26. if (i < board.length - 1 && board[i + 1][j] == 'O') {
  27. dfs(i + 1, j, board);
  28. }
  29. if (j > 0 && board[i][j - 1] == 'O') {
  30. dfs(i, j - 1, board);
  31. }
  32. if (j < board[0].length - 1 && board[i][j + 1] == 'O') {
  33. dfs(i, j + 1, board);
  34. }
  35. }
  36. }
  37. }

133 Clone Graph

https://leetcode.com/problems/clone-graph/

题目描述

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

OJ's undirected graph serialization:

Nodes are labeled uniquely.

We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.

As an example, consider the serialized graph {0,1,2#1,2#2,2}.

The graph has a total of three nodes, and therefore contains three parts as separated by #.

First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.

Visually, the graph looks like the following:

   1
  / \
 /   \
0 --- 2
     / \
     \_/

代码

  1. /**
  2. * Definition for undirected graph.
  3. * class UndirectedGraphNode {
  4. * int label;
  5. * List<UndirectedGraphNode> neighbors;
  6. * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
  7. * };
  8. */
  9. public class Solution {
  10. public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
  11. Map<Integer, UndirectedGraphNode> map = new HashMap<>();
  12. return dfs(node, map);
  13. }
  14. private UndirectedGraphNode dfs(UndirectedGraphNode node, Map<Integer, UndirectedGraphNode> map) {
  15. if (node == null) {
  16. return node;
  17. }
  18. if (map.containsKey(node.label)) {
  19. return map.get(node.label);
  20. }
  21. UndirectedGraphNode newNode = new UndirectedGraphNode(node.label);
  22. map.put(newNode.label, newNode);
  23. for (UndirectedGraphNode neighbors : node.neighbors) {
  24. newNode.neighbors.add(dfs(neighbors, map));
  25. }
  26. return newNode;
  27. }
  28. }

200 Number of Islands

https://leetcode.com/problems/number-of-islands/

题目描述

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 by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

11110
11010
11000
00000

Answer: 1
Example 2:

11000
11000
00100
00011

Answer: 3

Credits:Special thanks to @mithmatt for adding this problem and creating all test cases.

代码

  1. public class Solution {
  2. public void clearRestOfLand(int x, int y, char[][] grid) {
  3. if(x < 0 || y < 0 || x >= grid.length || y >= grid[0].length || grid[x][y] == '0'){
  4. return;
  5. }
  6. grid[x][y] = '0';
  7. clearRestOfLand(x - 1, y, grid);
  8. clearRestOfLand(x + 1, y, grid);
  9. clearRestOfLand(x, y - 1, grid);
  10. clearRestOfLand(x, y + 1, grid);
  11. }
  12. public int numIslands(char[][] grid) {
  13. int count = 0;
  14. for(int i = 0; i < grid.length; i++) {
  15. for(int j = 0; j < grid[0].length; j++) {
  16. if(grid[i][j] == '1') {
  17. count++;
  18. clearRestOfLand(i, j, grid);
  19. }
  20. }
  21. }
  22. return count;
  23. }
  24. }

207 Course Schedule

https://leetcode.com/problems/course-schedule/

题目描述

There are a total of n courses you have to take, labeled from 0 to n - 1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

For example:

2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

2, [[1,0],[0,1]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

Note:

The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
You may assume that there are no duplicate edges in the input prerequisites.

click to show more hints.

Hints:

代码

  1. class Solution {
  2. public boolean canFinish(int numCourses, int[][] pre) {
  3. // key 课程id,value 前置课程id
  4. Map<Integer, Set<Integer>> map = new HashMap<>();
  5. for (int i = 0; i < pre.length; i++) {
  6. if (map.containsKey(pre[i][0])) {
  7. map.get(pre[i][0]).add(pre[i][1]);
  8. } else {
  9. Set<Integer> set = new HashSet<>();
  10. set.add(pre[i][1]);
  11. map.put(pre[i][0], set);
  12. }
  13. }
  14. int[] visit = new int[numCourses];
  15. for (int i = 0; i < numCourses; i++) {
  16. if (!dfs(i, visit, map)) {
  17. return false;
  18. }
  19. }
  20. return true;
  21. }
  22. private boolean dfs(int i, int[] visit, Map<Integer, Set<Integer>> map) {
  23. if (visit[i] == -1) {
  24. return false;
  25. }
  26. if (visit[i] == 1) {
  27. return true;
  28. }
  29. visit[i] = -1;
  30. if (map.containsKey(i)) {
  31. for (int pre : map.get(i)) {
  32. if (!dfs(pre, visit, map)) {
  33. return false;
  34. }
  35. }
  36. }
  37. visit[i] = 1;
  38. return true;
  39. }
  40. }

210 Course Schedule II

https://leetcode.com/problems/course-schedule-ii/

题目描述

There are a total of n courses you have to take, labeled from 0 to n - 1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

For example:

2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1]

4, [[1,0],[2,0],[3,1],[3,2]]

There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3].

Note:

The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
You may assume that there are no duplicate edges in the input prerequisites.

click to show more hints.

Hints:

代码

  1. class Solution {
  2. public int[] findOrder(int numCourses, int[][] pre) {
  3. // key 课程id,value 前置课程id
  4. Map<Integer, Set<Integer>> map = new HashMap<>();
  5. for (int i = 0; i < pre.length; i++) {
  6. if (map.containsKey(pre[i][0])) {
  7. map.get(pre[i][0]).add(pre[i][1]);
  8. } else {
  9. Set<Integer> set = new HashSet<>();
  10. set.add(pre[i][1]);
  11. map.put(pre[i][0], set);
  12. }
  13. }
  14. int[] visit = new int[numCourses];
  15. List<Integer> ans = new ArrayList<>();
  16. for (int i = 0; i < numCourses; i++) {
  17. if (!dfs(i, visit, map, ans)) {
  18. return new int[0];
  19. }
  20. }
  21. int[] result = new int[numCourses];
  22. for(int i = 0; i < numCourses; i++){
  23. result[i] = ans.get(i);
  24. }
  25. return result;
  26. }
  27. private boolean dfs(int i, int[] visit, Map<Integer, Set<Integer>> map, List<Integer> ans) {
  28. if (visit[i] == -1) {
  29. return false;
  30. }
  31. if (visit[i] == 1) {
  32. return true;
  33. }
  34. visit[i] = -1;
  35. if (map.containsKey(i)) {
  36. for (int pre : map.get(i)) {
  37. if (!dfs(pre, visit, map,ans)) {
  38. return false;
  39. }
  40. }
  41. }
  42. visit[i] = 1;
  43. ans.add(i);
  44. return true;
  45. }
  46. }

329 Longest Increasing Path in a Matrix

https://leetcode.com/problems/longest-increasing-path-in-a-matrix/

题目描述

Given an integer matrix, find the length of the longest increasing path.

From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).

Example 1:

nums = [
  [9,9,4],
  [6,6,8],
  [2,1,1]
]

Return 4

The longest increasing path is [1, 2, 6, 9].

Example 2:

nums = [
  [3,4,5],
  [3,2,6],
  [2,2,1]
]

Return 4

The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.

Credits:Special thanks to @dietpepsi for adding this problem and creating all test cases.

代码

  1. public class Solution {
  2. public static final int[][] dirs = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
  3. public int robot(int x, int y, int[][] m, int[][] cache) {
  4. if(cache[x][y] != 0) return cache[x][y];
  5. int max = 1;
  6. for(int[] dir : dirs) {
  7. int dx = dir[0], dy = dir[1];
  8. if(x + dx < 0 || x + dx >= m.length || y + dy < 0 || y + dy >= m[0].length || m[x][y] <= m[x + dx][y + dy]) {
  9. continue;
  10. }
  11. // 同一个值反复调用,就会产生冗余,需要缓存结果
  12. max = Math.max(max, robot(x + dx, y + dy, m, cache) + 1);
  13. }
  14. cache[x][y] = max;
  15. return max;
  16. }
  17. public int longestIncreasingPath(int[][] matrix) {
  18. if(matrix.length == 0) return 0;
  19. int m = matrix.length, n = matrix[0].length;
  20. int[][] cache = new int[m][n];
  21. int ans = 1;
  22. // 枚举每一个点,计算每个点的最大升序
  23. for(int i = 0; i < m; i++) {
  24. for(int j = 0; j < n; j++) {
  25. ans = Math.max(ans, robot(i, j, matrix, cache));
  26. }
  27. }
  28. return ans;
  29. }
  30. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注