Leetcode之深度遍历递归与回溯法汇总
Posted Panda_Java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode之深度遍历递归与回溯法汇总相关的知识,希望对你有一定的参考价值。
分类刷题之深度遍历递归与回溯法2021.12.06
学习资料参考于:剑桥offer 和 C++ PDF刷题分类:第 6 章 一切皆可搜索
1. leetcode695 岛屿的最大面积 DFS
1.1 描述
1.2 代码
class Solution
public int maxAreaOfIsland(int[][] grid)
if(grid.length == 0)
return 0;
int area = 0;
for(int i = 0; i < grid.length; i ++)
for(int j = 0; j < grid[0].length; j++)
area = Math.max(area,dfs(grid,i,j));
return area;
public int dfs(int[][] grid, int m, int n)
if(m < 0 || m > grid.length-1 || n < 0 || n > grid[0].length-1 || grid[m][n] == 0)
return 0;
grid[m][n] = 0;
return dfs(grid,m -1, n) + dfs(grid, m + 1,n) + dfs(grid, m, n+1) + dfs(grid, m , n-1) + 1;
2. leetcode547 省份数量(朋友圈的个数)
2.1 描述
2.2 代码
class Solution
public int findCircleNum(int[][] isConnected)
int res = 0;
if(isConnected.length == 0)
return 0;
int a = isConnected.length;
boolean[] visit = new boolean[a];
for(int i = 0; i < visit.length; i++)
visit[i] = false;
for(int i = 0; i < visit.length; i++)
if(!visit[i])
dfs(isConnected,i,visit);
res = res +1;
return res;
public void dfs(int[][] isConnected, int j, boolean[] visit)
visit[j] = true;
for(int i = 0; i < isConnected.length; i++)
if(isConnected[j][i] == 1 && visit[i] == false)
dfs(isConnected,i,visit);
3. leetcode417 太平洋大西洋水流问题
3.1 描述
3.2 代码
class Solution
public List<List<Integer>> pacificAtlantic(int[][] heights)
List<List<Integer>> res = new ArrayList<>();
int m = heights.length;
if(m == 0)
return res;
int n = heights[0].length;
boolean[][] pacific = new boolean[m][n];
boolean[][] atlantic = new boolean[m][n];
// top and bottlom
for(int col = 0; col < n; col++)
dfs(heights,0,col,pacific,heights[0][col]);
dfs(heights,heights.length-1,col,atlantic,heights[heights.length-1][col]);
// left and right
for(int row = 0; row < m; row++)
dfs(heights,row,0,pacific,heights[row][0]);
dfs(heights,row,heights[0].length-1,atlantic,heights[row][heights[0].length-1]);
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
if(pacific[i][j]&&atlantic[i][j])
List<Integer> list = new ArrayList<>();
list.add(i);
list.add(j);
res.add(list);
return res;
private void dfs(int[][] heights,int c, int r, boolean[][] ocean, int preHeight)
if(c < 0 || c > heights.length-1 || r < 0 || r > heights[0].length-1 || heights[c][r] < preHeight || ocean[c][r])
return;
ocean[c][r] = true; //ocean 已经记录过;
dfs(heights,c - 1, r, ocean, heights[c][r]);
dfs(heights,c + 1, r, ocean, heights[c][r]);
dfs(heights,c, r - 1, ocean, heights[c][r]);
dfs(heights,c, r + 1, ocean, heights[c][r]);
4. leetcode46 全排列
4.1 描述
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
4.2 代码
class Solution
public List<List<Integer>> permute(int[] nums)
List<List<Integer>> res = new ArrayList<>();
List<Integer> list = new ArrayList<>();
boolean[] p = new boolean[nums.length];
for(int i = 0; i < nums.length; i++)
p[i] = false;
// 用于记录哪些访问过
backtracking(nums,res,list,p);
return res;
public void backtracking(int[] nums, List<List<Integer>> res,List<Integer> list1, boolean[] p)
if(list1.size()==nums.length)
List<Integer> temp = new ArrayList<>(list1); // 很关键
res.add(temp);
return; // 很容易遗忘
for(int i = 0; i < nums.length; i++)
if(!p[i]) // 按照以前i=start,不然只有[1,2,3]
list1.add(nums[i]);
p[i] = true; //多出来的一步
backtracking(nums,res,list1,p);
list1.remove(list1.size()-1); // 列表长度为list.size()
p[i] = false; //多出来的一步
5. leetcode77 组合
5.1 描述
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
5.2 代码
class Solution
public List<List<Integer>> combine(int n, int k)
List<List<Integer>> res = new ArrayList<>();
List<Integer> list = new ArrayList<>();
if(n < k)
return res;
backtracking(res,n,k,list,1);
return res;
public void backtracking(List<List<Integer>> res, int n, int k, List<Integer> list1, int start)
if(list1.size() == k)
List<Integer> temp = new ArrayList<>(list1); // 关键
res.add(temp);
return; // 关键
for(int i = start; i <= n; i++)
list1.add(i);
backtracking(res,n,k,list1,i+1);
list1.remove(list1.size()-1); // 关键
6. 剑指 Offer 13 机器人的运动范围
6.1 描述
写的代码只通过了案例的50%
6.2 代码
class Solution
public int movingCount(int m, int n, int k)
int res = 0;
boolean[][] nums = new boolean[m][n];
for(int p = 0; p < m; p++)
for(int q = 0; q < n; q++)
nums[p][q] = false;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
dfs(m,n,i,j,k,nums);
for(int p = 0; p < m; p++)
for(int q = 0; q < n; q++)
if(nums[p][q] == true)
res++;
return res;
public void dfs(int rows, int cols, int row, int col, int k, boolean[][] nums)
if(row < 0 || row > rows -1 || col < 0 || col > cols -1 ||check(row,col) > k || nums[row][col] == true)
return;
nums[row][col] = true;
dfs(rows,cols,row-1,col,k,nums);
dfs(rows,cols,row+1,col,k,nums);
dfs(rows,cols,row,col-1,k,nums);
dfs(rows,cols,row,col+1,k,nums);
public int check(int a, int b)
int cur1 = a/10;
int cur2 = a%10;
int cur3 = b/10;
int cur4 = b%10;
return cur1 + cur2 + cur3 + cur4;
7. leetcode17 电话号码的字母组合
链接: 自己写的电话号码的字母组合.
8. leetcode78 子集
链接: 自己写的子集.
以上是关于Leetcode之深度遍历递归与回溯法汇总的主要内容,如果未能解决你的问题,请参考以下文章
2021/6/13 刷题笔记括号生成与回溯法(深度优先遍历)