Leetcode之深度遍历递归与回溯法汇总

分类刷题之深度遍历递归与回溯法2021.12.06

  • 1. leetcode695 岛屿的最大面积 DFS
    • 1.1 描述
    • 1.2 代码
  • 2. leetcode547 省份数量(朋友圈的个数)
    • 2.1 描述
    • 2.2 代码
  • 3. leetcode417 太平洋大西洋水流问题
    • 3.1 描述
    • 3.2 代码
  • 4. leetcode46 全排列
    • 4.1 描述
    • 4.2 代码
  • 5. leetcode77 组合
    • 5.1 描述
    • 5.2 代码
  • 6. 剑指 Offer 13 机器人的运动范围
    • 6.1 描述
    • 6.2 代码
  • 7. leetcode17 电话号码的字母组合
  • 8. leetcode78 子集

学习资料参考于:剑桥offer 和 C++ PDF刷题分类:第 6 章 一切皆可搜索

1. leetcode695 岛屿的最大面积 DFS

1.1 描述

Leetcode之深度遍历递归与回溯法汇总_第1张图片
Leetcode之深度遍历递归与回溯法汇总_第2张图片

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;
    }
}

Leetcode之深度遍历递归与回溯法汇总_第3张图片

2. leetcode547 省份数量(朋友圈的个数)

2.1 描述

Leetcode之深度遍历递归与回溯法汇总_第4张图片
Leetcode之深度遍历递归与回溯法汇总_第5张图片

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 描述

Leetcode之深度遍历递归与回溯法汇总_第6张图片

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]);
    }
}

Leetcode之深度遍历递归与回溯法汇总_第7张图片

4. leetcode46 全排列

4.1 描述

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
Leetcode之深度遍历递归与回溯法汇总_第8张图片

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 个数的组合。
你可以按 任何顺序 返回答案。
Leetcode之深度遍历递归与回溯法汇总_第9张图片

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 描述

Leetcode之深度遍历递归与回溯法汇总_第10张图片
写的代码只通过了案例的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,leetcode,深度优先,算法)