leetcode之深度优先搜索刷题总结1
Posted nuist__NJUPT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode之深度优先搜索刷题总结1相关的知识,希望对你有一定的参考价值。
leetcode之深度优先搜索刷题总结1
1-岛屿数量
题目链接:题目链接戳这里!!!
思路:每个坐标点只要是1,就向上下左右四个方向搜索,每次搜索坐标点标为0, 每一轮搜索完就代表有一个岛屿。其实就是用dfs实现连通块的判断。
AC代码如下:
public class Solution
static int m, n ;
static int [] offsetX = 0,0,1,-1 ;
static int [] offsetY = 1,-1,0,0 ;
public int numIslands(char[][] grid)
int cnt = 0 ;
m = grid.length;
n = grid[0].length ;
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
if(grid[i][j] == '1')
cnt ++ ;
dfs(grid, i, j) ;
return cnt ;
private void dfs(char[][] grid, int x, int y)
grid[x][y] = '0' ;
for(int i=0; i<4; i++)
int nx = x + offsetX[i] ;
int ny = y + offsetY[i] ;
if(nx < 0 || ny < 0 || nx >= m || ny >=n)
continue;
if(grid[nx][ny] == '1')
dfs(grid, nx, ny) ;
2-二叉树的中序遍历
题目链接:题目链接戳这里!!!
思路:先遍历左子树,再遍历根节点,最后遍历右子树
AC代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode()
* TreeNode(int val) this.val = val;
* TreeNode(int val, TreeNode left, TreeNode right)
* this.val = val;
* this.left = left;
* this.right = right;
*
*
*/
class Solution
public List<Integer> inorderTraversal(TreeNode root)
List<Integer> res = new ArrayList<>() ;
inorder(root, res) ;
return res ;
public void inorder(TreeNode root, List<Integer> list)
if(root==null)
return ;
inorder(root.left, list) ; //中序遍历左子树
list.add(root.val) ; //中序遍历根节点
inorder(root.right, list) ; //中序遍历右子树
3-路径总和
题目链接:题目链接戳这里!!!
思路:先搜索左子树,再搜索右子树,每轮搜索到叶子节点检查是否满足路径和条件即可。
AC代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode()
* TreeNode(int val) this.val = val;
* TreeNode(int val, TreeNode left, TreeNode right)
* this.val = val;
* this.left = left;
* this.right = right;
*
*
*/
class Solution
boolean ans = false ;
public boolean hasPathSum(TreeNode root, int targetSum)
if(root==null)
return false ;
dfs(root, targetSum) ;
return ans ;
public void dfs(TreeNode root, int targetSum)
if(root==null) //一棵树遍历完了
return ;
if(root.left==null && root.right==null) //遍历到叶子节点
if(root.val==targetSum)
ans = true ;
return;
dfs(root.left, targetSum-root.val) ;//遍历左子树
dfs(root.right, targetSum-root.val) ;//遍历右子树
4-路径总和II
题目链接:题目链接戳这里!!!
思路:就是dfs,同时标记路径,满足条件便存储路径,直至完成搜索。
AC代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode()
* TreeNode(int val) this.val = val;
* TreeNode(int val, TreeNode left, TreeNode right)
* this.val = val;
* this.left = left;
* this.right = right;
*
*
*/
class Solution
List<List<Integer>> res = new ArrayList<>() ;
public List<List<Integer>> pathSum(TreeNode root, int targetSum)
if(root == null) //空树
return new ArrayList<>() ;
List<Integer> cur = new ArrayList<>() ;
dfs(root, cur, 0, targetSum) ; //搜索,并记录满足的路径
return res ;
public void dfs(TreeNode root, List<Integer> cur, int sum, int targetSum)
if(root == null)
return ;
if(root.left == null && root.right == null)//叶子节点
if(root.val+sum==targetSum) //满足条件
cur.add(root.val) ;
res.add(new ArrayList<>(cur)) ; //保存路径
cur.remove(cur.size()-1) ;
return ;
cur.add(root.val) ; //先记录
dfs(root.left, cur, root.val+sum, targetSum) ; //搜索左子树
dfs(root.right, cur, root.val+sum, targetSum) ; //搜索右子树
cur.remove(cur.size()-1) ; //每一轮搜索后要将最后一个删掉
5-被围绕的区域
题目链接:题目链接戳这里!!!
思路:需要三轮搜索
第一轮,搜索四个边界,把是O且联通的都标记为+
第二轮,搜索中间的所有,把O都标记为X
第三轮,搜索四个边界,把是+的都改成O
AC代码如下:
class Solution
int [] offsetX = 0,0,-1,1 ;
int [] offsetY = 1,-1,0,0 ;
public void solve(char[][] board)
int m = board.length ;
int n = board[0].length ;
for(int i=0; i<m; i++)
if(board[i][0]=='O' )
dfs(board, i, 0) ;
if(board[i][n-1]=='O')
dfs(board, i, n-1);
for(int j=0; j<n; j++)
if(board[0][j] == 'O')
dfs(board, 0, j) ;
if(board[m-1][j]=='O')
dfs(board, m-1, j) ;
for(int i=1; i<m-1; i++)
for(int j=1; j<n-1; j++)
if(board[i][j] == 'O')
dfs1(board, i, j) ;
for(int i=0; i<m; i++)
if(board[i][0]=='+' )
dfs2(board, i, 0) ;
if(board[i][n-1]=='+')
dfs2(board, i, n-1);
for(int j=0; j<n; j++)
if(board[0][j] == '+')
dfs2(board, 0, j) ;
if(board[m-1][j]=='+')
dfs2(board, m-1, j) ;
public void dfs(char[][]a, int x, int y)
int m = a.length ;
int n = a[0].length ;
a[x][y] = '+' ;
for(int i=0; i<4; i++)
int nx = x + offsetX[i] ;
int ny = y + offsetY[i] ;
if(nx<0 || ny<0 || nx>m-1 || ny>n-1)
continue ;
if(a[nx][ny] == 'O')
dfs(a, nx, ny) ;
public void dfs1(char[][]a, int x, int y)
int m = a.length ;
int n = a[0].length ;
a[x][y] = 'X' ;
for(int i=0; i<4; i++)
int nx = x + offsetX[i] ;
int ny = y + offsetY[i] ;
if(nx<1 || ny<1 || nx>m-2 || ny>n-2)
continue ;
if(a[nx][ny] == 'O')
dfs1(a, nx, ny) ;
public void dfs2(char[][]a, int x, int y)
int m = a.length ;
int n = a[0].length ;
a[x][y] = 'O' ;
for(int i=0; i<4; i++)
int nx = x + offsetX[i] ;
int ny = y + offsetY[i] ;
if(nx<0 || ny<0 || nx>m-1 || ny>n-1)
continue ;
if(a[nx][ny] == '+')
dfs2(a, nx, ny) ;
6-二叉树的前序遍历
题目链接:题目链接戳这里!!!
思路:先搜索根,再搜索左子树,再搜索右子树
AC代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode()
* TreeNode(int val) this.val = val;
* TreeNode(int val, TreeNode left, TreeNode right)
* this.val = val;
* this.left = left;
* this.right = right;
*
*
*/
class Solution
public List<Integer> preorderTraversal(TreeNode root)
List<Integer> list = new ArrayList<>() ;
preOrder(root, list) ;
return list ;
public void preOrder(TreeNode root, List<Integer> list)
if(root==null)
return ;
list.add(root.val) ;
preOrder(root.left, list) ;
preOrder(root.right, list) ;
7-二叉树的后序遍历
题目链接:题目链接戳这里!!!
思路:先搜索左子树,再搜索右子树,最后搜索根节点
AC代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode()
* TreeNode(int val) this.val = val;
* TreeNode(int val, TreeNode left, TreeNode right)
* this.val = val;
* this.left = left;
* this.right = right;
*
*
*/
class Solution
public List<Integer> postorderTraversal(TreeNode root)
List<Integer> list = new ArrayList<>() ;
postOrder(root, list) ;
return list ;
public void postOrder(TreeNode root, List<Integer> list)
if(root== null)
return ;
postOrder(root.left, list) ;
postOrder(root.right, list) ;
list.add(root.val) ;
8-打家劫舍III
题目链接:题目链接戳这里!!!
思路:搜索左右子树,记录偷与不偷当前节点可以获得的最大钱,递归下去,最后返回两个值,选最大的即可。
AC代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode()
* TreeNode(int val) this.val = val;
* TreeNode(int val, TreeNode left, TreeNode right)
* this.val = val;
* this.left = left;
* this.right = right;
*
*
*/
class Solution
public int rob(TreeNode root)
leetcode之深度优先搜索刷题总结3