0
点赞
收藏
分享

微信扫一扫

更改一列checkbox的顺序

践行数据分析 2024-10-14 阅读 21

递归,回溯,剪枝

 

文章顺序:

题目链接=》算法原理=》代码呈现

思想总结:

1. 二叉树剪枝

题目链接:

814. 二叉树剪枝 - 力扣(LeetCode)

算法思路:

        如果我们选择从上往下删除,我们需要收集左右⼦树的信息,这可能导致代码编写相对困难。然⽽,通过观察我们可以发现,如果我们先删除最底部的叶⼦节点,然后再处理删除后的节点,最终的结果并不会受到影响。

        因此,我们可以采⽤后序遍历的⽅式来解决这个问题。在后序遍历中,我们先处理左⼦树,然后处理右⼦树,最后再处理当前节点。在处理当前节点时,我们可以判断其是否为叶⼦节点且其值是否为 0,如果满⾜条件,我们可以删除当前节点。

  • 需要注意的是,在删除叶⼦节点时,其⽗节点很可能会成为新的叶⼦节点。因此,在处理完⼦节点后,我们仍然需要处理当前节点。这也是为什么选择后序遍历的原因(后序遍历⾸先遍历到的⼀定是叶⼦节点)。
  • 通过使⽤后序遍历,我们可以逐步删除叶⼦节点,并且保证删除后的节点仍然满⾜删除操作的要求。这样,我们可以较为⽅便地实现删除操作,⽽不会影响最终的结果。
  • 若在处理结束后所有叶⼦节点的值均为 1,则所有⼦树均包含 1,此时可以返回。

代码呈现:

class Solution {
    public TreeNode pruneTree(TreeNode root) {
       return dfs(root);
    }
    private TreeNode dfs(TreeNode root){
        if(root==null){return root;}
        if(root.left==null&&root.right==null){
            if(root.val==0){
                return null;
            }else{
                return root;
            }
        }
        TreeNode left=dfs(root.left);
        TreeNode right=dfs(root.right);
        root.left=left;
        root.right=right;
        if(left==null&&right==null&&root.val==0){
            root=null;
        }
        return root;
    }
}

2.二叉搜索树中第k小的元素

题目链接: 

230. 二叉搜索树中第 K 小的元素 - 力扣(LeetCode)

算法思路:

算法流程:

定义⼀个全局的变量 count,在主函数中初始化为 k 的值(不⽤全局也可以,当成参数传⼊递归过程中)。

递归函数的设计:int dfs(TreeNode* root): (返回值为第 k 个结点)。

递归函数流程(中序遍历):

1.递归出⼝:空节点直接返回 -1,说明没有找到;

2.去左⼦树上查找结果,记为 retleft:

  • 如果 retleft == -1,说明没找到,继续执⾏下⾯逻辑;
  • 如果 retleft != -1,说明找到了,直接返回结果,⽆需执⾏下⾯代码(剪枝);

3.如果左⼦树没找到,判断当前结点是否符合:

  • 如果符合,直接返回结果

4.如果当前结点不符合,去右⼦树上寻找结果。

代码呈现:

class Solution {
    int ret;
    int n;
    public int kthSmallest(TreeNode root, int k) {
       n=k;
       return dfs(root);   
    }
    private int dfs(TreeNode root){
        if(n==0) return ret;
        if(root.left==null&&root.right==null){
            if(n!=0)
            {n--;
            ret=root.val;
            }return ret;
        } 
       if(root.left!=null) dfs(root.left);
       if(n!=0){n--;
       ret=root.val;
       }if(n==0) return ret;
       if(root.right!=null) dfs(root.right);
       return ret;
    }
}

3.二叉树的所有路径

题目链接:

257. 二叉树的所有路径 - 力扣(LeetCode)

算法思路:

使⽤深度优先遍历(DFS)求解。

路径以字符串形式存储,从根节点开始遍历,每次遍历时将当前节点的值加⼊到路径中,如果该节点为叶⼦节点,将路径存储到结果中。否则,将 "->" 加⼊到路径中并递归遍历该节点的左右子树。

定义⼀个结果数组,进⾏递归。递归具体实现⽅法如下:

  1. 如果当前节点不为空,就将当前节点的值加⼊路径 path 中,否则直接返回;
  2. 判断当前节点是否为叶⼦节点,如果是,则将当前路径加⼊到所有路径的存储数组 paths 中;
  3. 否则,将当前节点值加上 "->" 作为路径的分隔符,继续递归遍历当前节点的左右⼦节点。
  4. 返回结果数组。

具体实现⽅法如下:

  1. 定义⼀个结果数组和⼀个路径数组。
  2. 从根节点开始递归,递归函数的参数为当前节点、结果数组和路径数组。                                      
  3. 返回结果数组。

代码呈现:

class Solution {
    List<String> ret=new ArrayList<>();
    public List<String> binaryTreePaths(TreeNode root) {
      String path="";
      dfs(root,path);
      return ret;
    }
    private void dfs(TreeNode root,String path){
       if(root.left==null&&root.right==null){
        path+=""+root.val;
        ret.add(path);
        return;
       }
       path+=root.val+"->";
       if(root.left!=null){
        dfs(root.left,path);
       }
       if(root.right!=null) dfs(root.right,path);
       return;
    }    
}
举报

相关推荐

0 条评论