码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • LeetCode 热题 HOT 100:回溯专题


    LeetCode 热题 HOT 100:https://leetcode.cn/problem-list/2cktkvj/


    文章目录

      • 17. 电话号码的字母组合
      • 22. 括号生成
      • 39. 组合总和
      • 46. 全排列
      • 补充:47. 全排列 II (待优化)
      • 78. 子集
      • 79. 单词搜索
      • 124. 二叉树中的最大路径和
      • 200. 岛屿数量
      • 437. 路径总和 III


    17. 电话号码的字母组合

    题目链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    class Solution {
        List<String> list;
        Map<Character, String> map;
    
        public List<String> letterCombinations(String digits) {
            ap = new HashMap<>();
            res = new LinkedList<>();
            if(digits.length() == 0){
                return res;
            }
            map.put('2', "abc");
            map.put('3', "def");
            map.put('4', "ghi");
            map.put('5', "jkl");
            map.put('6', "mno");
            map.put('7', "pqrs");
            map.put('8', "tuv");
            map.put('9', "wxyz");
            backTrack(digits, 0, new StringBuilder());
            return list;
        }
    
        public void backTrack(String digits, int ind, StringBuilder sb){ // 参数:输入的字符串、字符串的索引、拼接的英文字符串
            if(digits.length() == ind){
                list.add(sb.toString());
            }else{
                char ch = digits.charAt(ind);
                String str = map.get(ch); // 获取按键下面的字符序列
                for (int i = 0; i < str.length(); i++) {
                    sb.append(str.charAt(i));
                    backTrack(digits, ind + 1, sb);
                    sb.deleteCharAt(sb.length()-1); // 回溯
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    参考题解:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/solutions/388738/dian-hua-hao-ma-de-zi-mu-zu-he-by-leetcode-solutio/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    在这里插入图片描述


    22. 括号生成

    题目链接:https://leetcode.cn/problems/generate-parentheses/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    思路一:

    class Solution {
        List<String> res;
        public List<String> generateParenthesis(int n) {
            res = new LinkedList<>();
            backTrack(n, 0, 0, "");
            return res;
        }
    
        public void backTrack(int n, int left, int right, String str){
            if(left < right){
                return;
            }
            if(left == n && right == n){
                res.add(str);
                return;
            }else{
                if(left < n){
                    backTrack(n, left+1, right, str+"(");
                }
                backTrack(n, left, right+1, str+")");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    思路二:

    class Solution {
        List<String> res = new ArrayList<>();
        public List<String> generateParenthesis(int n) {
            if(n<=0){
                return res;
            }
            getBracket("", n, n);
            return res;
        }
    
        public void getBracket(String str, int left, int right){
            if(left == 0 && right == 0){
                res.add(str);
                return;
            }
            if(left == right){
                getBracket(str+"(", left-1, right);
            }else{
                if(left > 0){
                    getBracket(str+"(", left-1, right);
                }
                getBracket(str+")", left, right-1);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    39. 组合总和

    题目链接:https://leetcode.cn/problems/combination-sum/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    class Solution {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
    
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            dfs(candidates, target, 0);
            return res;
        }
    
        public void dfs(int[] candidates, int target, int ind){ // 关键点在于索引
            if(target == 0){
                res.add(new ArrayList<>(list));
                return;
            }
    
            for(int i = ind; i < candidates.length; i ++){
                if(target - candidates[i] >= 0){
                    list.add(candidates[i]);
                    dfs(candidates, target - candidates[i], i); 
    			    // 每次在当前的索引上进行遍历,作用在于:如果没有索引:target=5,5-3-2 作用等同于 5-2-3, 那么会有两种组合[2,3]与[3,2]
                    // 但是在索引的约束下,不会出现这种情况 
                    list.remove(list.size()-1);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    参考链接:https://leetcode.cn/problems/combination-sum/solutions/14697/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-m-2/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj
    在这里插入图片描述


    46. 全排列

    题目链接:https://leetcode.cn/problems/permutations/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    class Solution {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
    
        public List<List<Integer>> permute(int[] nums) {
            boolean[] visited = new boolean[nums.length]; // 标志数组
            dfs(nums, 0, visited);
            return res;
        }
    
        public void dfs(int[] nums, int size, boolean[] visited){
            if(size == nums.length){
                res.add(new ArrayList<>(list));
                return;
            }
            for(int i = 0; i < nums.length; i ++){
                if(!visited[i]){
                    visited[i] = true;
                    list.add(nums[i]);
                    dfs(nums, size+1, visited);
                    list.remove(list.size()-1); // 回溯
                    visited[i] = false;
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    参考链接:https://leetcode.cn/problems/permutations/solutions/9914/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    在这里插入图片描述


    补充:47. 全排列 II (待优化)

    题目链接:https://leetcode.cn/problems/permutations-ii/description/?envType=featured-list&envId=2cktkvj%3FenvType%3Dfeatured-list&envId=2cktkvj

    class Solution {
        List<List<Integer>> res = new LinkedList<>();
        List<Integer> list = new LinkedList<>();
    
        public List<List<Integer>> permuteUnique(int[] nums) {
            boolean[] visited = new boolean[nums.length]; // 标志数组
            dfs(nums, 0, visited);
            return res;
        }
    
        public void dfs(int[] nums, int size, boolean[] visited){
            if(size == nums.length){
                for (List<Integer> result : res) {
                    if(result.equals(list)){
                        return;
                    }
                }
                res.add(new ArrayList<>(list));
                return;
            }
            for(int i = 0; i < nums.length; i ++){
                if(!visited[i]){
                    visited[i] = true;
                    list.add(nums[i]);
                    dfs(nums, size+1, visited);
                    list.remove(list.size()-1);
                    visited[i] = false;
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    78. 子集

    题目链接:https://leetcode.cn/problems/subsets/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    class Solution {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
    
        public List<List<Integer>> subsets(int[] nums) {
            dfs(nums, 0);
            return res;
        }
    
        public void dfs(int[] nums, int i){
            if(i==nums.length){
                res.add(new ArrayList(list));
                return;
            }
            // 选 nums[i]
            list.add(nums[i]);
            dfs(nums, i+1);
            // 不选 nums[i]
            list.remove(list.size()-1);
            dfs(nums, i+1);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述


    79. 单词搜索

    题目链接:https://leetcode.cn/problems/word-search/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    class Solution {
    
        public boolean exist(char[][] board, String word) {
            for(int i = 0; i < board.length; i ++){
                for(int j = 0; j < board[0].length; j ++){
                    if(board[i][j] == word.charAt(0)){
                        if(dfs(board, i, j, word, 0)){ // 路径开头不一定只有一处,所以要遍历整个数组
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    
        public boolean dfs(char[][] board, int i, int j, String word, int ind){
            if(ind >= word.length()){
                return true;
            }
            if(i>=0 && i<board.length && j>=0 && j<board[0].length && board[i][j]==word.charAt(ind) && board[i][j]!='\0'){ // 剪枝
                char tmp = board[i][j];
                board[i][j] = '\0'; // 设置不可访问
                boolean f1 = dfs(board, i, j-1, word, ind+1); // 左
                boolean f2 = dfs(board, i-1, j, word, ind+1); // 上
                boolean f3 = dfs(board, i, j+1, word, ind+1); // 右
                boolean f4 = dfs(board, i+1, j, word, ind+1); // 下
                board[i][j] = tmp; // 回溯
                return f1 || f2 || f3 ||f4;
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    124. 二叉树中的最大路径和

    题目链接:https://leetcode.cn/problems/binary-tree-maximum-path-sum/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    • 二叉树 abc,a 是根结点(递归中的 root),bc 是左右子结点(代表其递归后的最优解)。最大的路径,可能的路径情况:
         a
       /  \
        b    c
      ① b + a + c。
      ② b + a + a 的父结点。(需要再次递归)
      ③ a + c + a 的父结点。(需要再次递归)
    • 其中情况 1,表示如果不联络父结点的情况,或本身是根结点的情况。这种情况是没法递归的,但是结果有可能是全局最大路径和,因此可以在递归过程中通过比较得出。
    • 情况 2 和 3,递归时计算 a+b 和 a+c,选择一个更优的方案返回,也就是上面说的递归后的最优解。
    class Solution {
        int max = Integer.MIN_VALUE;
    
        public int maxPathSum(TreeNode root) {
            if(root == null){
                return 0;
            }
            dfs(root);
            return max;
        }
    
        /**
         * 返回经过root的单边分支最大和, 即 Math.max(root, root+left, root+right)
         */
        public int dfs(TreeNode root){
            if(root == null){
                return 0;
            }
            // 计算左子树最大值,左边分支如果为负数还不如不选择
            int leftMax = Math.max(0, dfs(root.left));
            // 计算右子树最大值,右边分支如果为负数还不如不选择
            int rightMax = Math.max(0, dfs(root.right));
    
            // left->root->right 作为路径与已经计算过历史最大值做比较
            max = Math.max(max, leftMax + root.val + rightMax);
    
            // 返回经过root的单边最大分支给当前root的父节点计算使用
            return root.val + Math.max(leftMax, rightMax);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    200. 岛屿数量

    题目链接:https://leetcode.cn/problems/number-of-islands/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

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

    437. 路径总和 III

    题目链接:https://leetcode.cn/problems/path-sum-iii/description/?envType=featured-list&envId=2cktkvj?envType=featured-list&envId=2cktkvj

    class Solution {
        // key 是前缀和,value 是前缀和为这个值的路径数量。
        Map<Long, Integer> map = new HashMap<>();
        int target;
    
        public int pathSum(TreeNode root, int targetSum) {
            this.target = targetSum;
            // 可能路径从根节点开始算
            map.put(0l, 1);
            return dfs(root, 0l);
        }
    
        public int dfs(TreeNode root, long curSum){
            if(root == null){
                return 0;
            }
            curSum += root.val; // 当前累计的结点值
            int res = 0;
            // 以当前节点为止,去查看从前的 map 集合中是否还存在目标前缀和
            //              1
            //             /
            //            2
            //           /
            //          3
            // 假设目标和为 5
            // 节点 1 的前缀和为:1
            // 节点 3 的前缀和为: 1+2+3 = 6
            // pre(3) - pre(1) = 5
            // 所以从节点 1 到节点 3 之间有一条符合要求的路径
            res += map.getOrDefault(curSum-target, 0);
    
            // 存储路径的原因是可能节点的前缀和存在相等的情况:
            //              2
            //             /
            //            0
            //           /
            //          4
            // 从节点 2 到节点 4 有两条路径长度等于2
            map.put(curSum, map.getOrDefault(curSum, 0) + 1);
    
            int left = dfs(root.left, curSum); // 调用左子树
            int right = dfs(root.right, curSum); // 调用右子树
    
            res = res + left + right;
    
            map.put(curSum, map.get(curSum)-1); // 恢复状态
    
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

  • 相关阅读:
    MongoDB聚合运算符:$zip
    C++中关于多线程并发访问实例函数与静态函数
    geneious中有的功能无法使用
    数据结构绪论、顺序表课后练习题
    创建一个新的IDEA插件项目
    jumpserver如何录入web资产
    你想要创建一个属于自己的网站吗?十大免费网站
    centos7 怎么让命令行显示中文(英文->中文)
    提示词优化的自动化探索:Automated Prompt Engineering
    Java练习 day6
  • 原文地址:https://blog.csdn.net/weixin_43819566/article/details/133467704
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号