669. 修剪二叉搜索树
不能简单地通过递归实现代码,比如:
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == nullptr || root->val < low || root->val > high) return nullptr;
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
return root;
}
};
举例:
在遍历到0这个结点时,因为0满足递归的第一个条件,所以会直接将0的所有子树删除,但是0的右子树的节点满足[1,3]这个范围.
其实就是要考虑0节点右子树
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if(root==null) return null;
if(root.val<low){
return trimBST(root.right,low,high);
}
if(root.val>high){
return trimBST(root.left,low,high);
}
root.left=trimBST(root.left,low,high);
root.right=trimBST(root.right,low,high);
return root;
}
}
108. 将有序数组转换为二叉搜索树
这道题强调平衡,是怕给出了一个升序的数组后,建立的二叉树是这样的:
如果默认从数组的中间位置开始构建,以中间的节点作为根节点,然后递归的构建左子树和右子树,这个二叉树自然就是平衡的
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums.length==0) return null;
return buildTree(nums,0,nums.length-1);
}
public TreeNode buildTree(int[] nums,int low,int high){
if(low>high) return null;
int mid=(low+high)/2;
TreeNode root=new TreeNode(nums[mid]);
root.left=buildTree(nums,low,mid-1);
root.right=buildTree(nums,mid+1,high);
return root;
}
}
注意:
在Java中,由运算结果,由被运算数的最高数据类型决定(float比int类型高)
538. 把二叉搜索树转换为累加树
题中给出的例子:
根据答案:就是二叉搜索树遍历的顺序是[0,1,2,3,4,5,6,7,8],而累加树遍历的顺序是相反的,从8开始。所以在二叉搜索树上就是按照右中左的遍历顺序
哈哈,看完答案的思路之后自己写的代码,竟然是对的,比答案还简单,真开心!
class Solution {
int val=0;//用于存储当前便利的结点之和
public TreeNode convertBST(TreeNode root) {
if(root==null) return null;
root.right=convertBST(root.right);
root.val+=val;
val=root.val;
root.left=convertBST(root.left);
return root;
}
}
回溯算法
1、回溯函数也就是递归函数,指的都是一个函数。
2、回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案,回溯法并不是什么高效的算法。
3、主要解决的问题种类:
组合问题:N个数里面按一定规则找出k个数的集合
切割问题:一个字符串按一定规则有几种切割方式
子集问题:一个N个数的集合里有多少符合条件的子集
排列问题:N个数按一定规则全排列,有几种排列方式
棋盘问题:N皇后,解数独等等
4、关于组合和排列:
组合是不强调元素顺序的,排列是强调元素顺序
5、模板
习惯是函数起名字为backtracking
回溯算法中函数返回值一般为void
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}