654.最大二叉树
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
- 二叉树的根是数组中的最大元素。
- 左子树是通过数组中最大值左边部分构造出的最大二叉树。
- 右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
示例 :
提示:
给定的数组的大小在 [1, 1000] 之间。
解析:
题目所示,先找出最大值为根,然后根据最大值左边构建左子树,最大值右边构建右子树,天然的前序遍历构建二叉树。
递归三部曲->(左闭右开区间)
1、确定递归函数的参数和返回值
2、确定终止条件:传入的数组大小为1,说明遍历到了叶子节点,这时候应该定义一个新的节点,并把数组的数值复制给新的节点。
3、确定单层递归逻辑:
3.1-找到数组中最大的值和对应的下标,最大值构建根节点,下标用来下一步分隔数组。
3.2-最大值所在下标的左区间构造左子树
3.3-最大值所在下标的右区间构造右子树
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return function(nums,0,nums.length);
}
public TreeNode function(int[] nums, int left, int right){
if(right - left < 1){
return null;
}
if(right - left == 1){
return new TreeNode(nums[left]);
}
int maxIndex = left;
int maxValue = nums[maxIndex];
for(int i = left+1; i < right; i++){
if(nums[i] > maxValue){
maxValue = nums[i];
maxIndex = i;
}
}
TreeNode root = new TreeNode(maxValue);
//左闭右开
root.left = function(nums,left,maxIndex);
//左闭右开
root.right = function(nums,maxIndex+1,right);
return root;
}
}
617.合并二叉树
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
示例 1:
注意: 合并必须从两个树的根节点开始。
解析:
比较简单,分几种情况讨论,然后前序遍历相加即可。
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
//递归
if(root1 == null && root2 == null){
return null;
}
if(root1 != null && root2 == null){
return root1;
}
if(root1 == null && root2 != null){
return root2;
}
TreeNode root = new TreeNode(root1.val + root2.val);
root.left = mergeTrees(root1.left, root2.left);
root.right = mergeTrees(root1.right,root2.right);
return root;
}
}
700.二叉搜索树中的搜索
给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。
例如,
在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 NULL
解析:
递归法比较简单,也是可以用前序遍历的方法,但要注意,不能直接的调用searchBST函数,因为这个函数是有返回值的,需要有个变量来承接该函数。
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root == null || root.val == val) return root;
TreeNode left = searchBST(root.left,val);
if(left != null) return left;
return searchBST(root.right,val);
}
}
注意到这是二叉搜索树,所以可以有优化方案:
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root == null || root.val == val) return root;
if(root.val > val) return searchBST(root.left,val);
else return searchBST(root.right,val);
}
}
98.验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
解析:
1、递归法,因为是BST,所以要注意中序遍历的话一定是有序的,这题我是直接看的题解,所以没有踩那几个陷阱。但我拿到题目的第一反应,也是打算淡出的比较左节点小于中间节点,右节点大于中间节点就完事了。这是错误的,只有左子树的全部节点小于根节点,右子树的全部节点大于根节点才算有效BST。这时候就需要一个max作为中间节点,只要左子树中的max节点是小于根节点即可满足要求。
单层递归逻辑:中序遍历max,只要max >= root.val, 就返回false
class Solution {
TreeNode max;
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
boolean left = isValidBST(root.left);
if(!left) return false;
if(max != null && max.val >= root.val)
return false;
max = root;
boolean right = isValidBST(root.right);
return right;
}
}
2、利用二叉搜索树特性,中序遍历是有序的,可以把值都保存到一个数组中,然后判断这个数组是否有序
class Solution {
List<Integer> list = new ArrayList<>();
public boolean isValidBST(TreeNode root) {
search(root);
for(int i = 1; i < list.size(); i++){
if(list.get(i) <= list.get(i-1)){
return false;
}
}
return true;
}
public void search(TreeNode root){
if(root == null) return;
//左
search(root.left);
//中
list.add(root.val);
//右
search(root.right);
}
}
3、迭代法:这个比较生疏,照着题解看一眼回顾回顾
class Solution {
public boolean isValidBST(TreeNode root) {
if(root == null){
return true;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode pre = null;
while(root != null || !stack.isEmpty()){
while(root != null){
stack.push(root);
root = root.left;
}
TreeNode pop = stack.pop();
if(pre != null && pop.val <= pre.val)
return false;
pre = pop;
root = pop.right;
}
return true;
}
}
标签:TreeNode,val,二叉,搜索,二叉树,return,root,节点,left
From: https://blog.51cto.com/u_15505301/7427754