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

Posted Panda_Java

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode之深度遍历递归与回溯法汇总相关的知识,希望对你有一定的参考价值。


学习资料参考于:剑桥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之深度遍历递归与回溯法汇总的主要内容,如果未能解决你的问题,请参考以下文章

leetcode算法题基础(四十二) 回溯算法总结

2021/6/13 刷题笔记括号生成与回溯法(深度优先遍历)

广度优先遍历和深度优先遍历的真正区别

LeetCode二叉树#16二叉树的最近公共祖先(递归后序遍历,巩固回溯机制)

八皇后回溯计算法研究

一文通数据结构与算法之——回溯算法+常见题型与解题策略+Leetcode经典题