递归,回溯,剪枝
想必大家再学习算法知识的路上经常听到回溯,剪枝类似的概念,对于初学者来说,很容易把他们理解成一种新的算法思想,其实回溯和剪枝只是在递归的基础上稍加修改,对于解决某些特定问题非常有帮助,我从力扣上选了三道题,我会粘贴题目链接,并对每道题进行详细的原理分析,希望大家能坚持看完,绝对能有收获,大家有更好的思路也欢迎大家在评论区交流啊!
文章顺序:
题目链接=》算法原理=》代码呈现
思想总结:
回溯:从⼀个初始状态开始,按照⼀定的规则向前搜索,当搜索到某个状态⽆法前进时,回退到前⼀个状态,再按照其他的规则搜索。回溯算法在搜索过程中维护⼀个状态树,通过遍历状态树来实现对所有可能解的搜索。
剪枝:如在二叉树中搜索某数时,通过在递归函数执行之前加一层条件判断的方式判断是否已经找到要找的数了,如果找到了便可以不用进入下面的递归函数,以此实现节省时间和空间的目的。
1. 二叉树剪枝
题目链接:
814. 二叉树剪枝 - 力扣(LeetCode)
算法思路:
- 需要注意的是,在删除叶⼦节点时,其⽗节点很可能会成为新的叶⼦节点。因此,在处理完⼦节点后,我们仍然需要处理当前节点。这也是为什么选择后序遍历的原因(后序遍历⾸先遍历到的⼀定是叶⼦节点)。
- 通过使⽤后序遍历,我们可以逐步删除叶⼦节点,并且保证删除后的节点仍然满⾜删除操作的要求。这样,我们可以较为⽅便地实现删除操作,⽽不会影响最终的结果。
- 若在处理结束后所有叶⼦节点的值均为 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)
算法思路:
- 如果 retleft == -1,说明没找到,继续执⾏下⾯逻辑;
- 如果 retleft != -1,说明找到了,直接返回结果,⽆需执⾏下⾯代码(剪枝);
- 如果符合,直接返回结果
代码呈现:
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)
算法思路:
- 如果当前节点不为空,就将当前节点的值加⼊路径 path 中,否则直接返回;
- 判断当前节点是否为叶⼦节点,如果是,则将当前路径加⼊到所有路径的存储数组 paths 中;
- 否则,将当前节点值加上 "->" 作为路径的分隔符,继续递归遍历当前节点的左右⼦节点。
- 返回结果数组。
特别地,我们可以只使⽤⼀个字符串存储每个状态的字符串,在递归回溯的过程中,需要将路径中的当前节点移除,以回到上⼀个节点。
- 定义⼀个结果数组和⼀个路径数组。
- 从根节点开始递归,递归函数的参数为当前节点、结果数组和路径数组。
a. 如果当前节点为空,返回。b. 将当前节点的值加⼊到路径数组中。c. 如果当前节点为叶⼦节点,将路径数组中的所有元素拼接成字符串,并将该字符串存储到结果数组中。d. 递归遍历当前节点的左⼦树。e. 递归遍历当前节点的右⼦树。f. 回溯,将路径数组中的最后⼀个元素移除,以返回到上⼀个节点。
- 返回结果数组。
代码呈现:
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;
}
}
❤️😍😍😍😍😍😍😍😍😍😍😍😍😍😍😍😍😍
🍔我是小皮侠,谢谢大家都能看到这里!!
🦚主页已更新Java基础内容,数据结构基础,数据库,算法,Redis相关内容。
🚕未来会更新Java项目,SpringBoot,docker,mq,微服务以及各种Java路线会用到的技术。
🎃求点赞!求收藏!求评论!求关注!
🤷♀️谢谢大家!!!!!!!!