654.最大二叉树
构造二叉树,要想到用“前序遍历。”
思路
首先在给出数组中找到值最大的数,然后构造它为根节点;然后以这个数为分界点,数组被分到的左边和右边,那么这左边和右边又各自去找找最大值然后分别作为已构造的根节点的左右子树;然后继续递归下去,左节点又作为一个根节点和分界线去找到它对应的左右子树,右子树也一样,之后都按照这个规律方式;这里需要强调一点是:这个方法的参数包括数组、数组开始索引、数组结束索引。
—如何找到最大数值呢?
按照首先默认数组首个数是最大的,最大值的索引也为第一个数的下标,然后依次和第一个数以后的数比较,若有更大的则重新对最大值和最大下标索引赋值。
—按照数组长度进行一些判断?
数组长度为未索引-首索引
1.若相减后=1,表示只有一个元素,那构造这个为根节点并返回;
2.若相减后<1,说明数组中不存在元素,那就返回null。
注意
要注意区间是什么,左闭右闭和左闭右开,选择了一个区间选择,就得全程都按照区间要求,可以想一下“二分搜索”。
实现代码
//构造二叉树类的题目都要用前序遍历
//“左闭右开”原则
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return construct(nums,0,nums.length);
}
public TreeNode construct(int [] nums,int left,int right){
if(right-left<1){
return null;
}
if(right-left==0){
return new TreeNode(nums[left]);
}
int maxindex=left;
int maxvalue=nums[left];
for(int i=left+1;i<right;i++){
if(maxvalue<nums[i]){
maxvalue=nums[i];
maxindex=i;
}
}
TreeNode root=new TreeNode(maxvalue);
root.left=construct(nums,left,maxindex);
root.right=construct(nums,maxindex+1,right);
return root;
}
}
617.合并二叉树
思路
合并二叉树是将两棵二叉树合并为一,这说明要同时操作两颗树,之前对称二叉树里面就有同时操作两树的经历。
我们可以选择合并后的二叉树是利用一个新树去放还是用两棵之中的树去放,我是使用root1来变成合并后的二叉树,所以利用root1的值去相加改变;实现过程:首先判断当root1为空时,返回root2;当root2为空时返回root1,这里是包含了两树同时为空的情况;然后是合并树的左右子树,利用递归,两树的左对应左,右对应右。
注意
在两棵二叉树上是同时遍历的,所以每次走到的对应位置都是相同的。
实现代码
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
//通过改变root1树获得最后合并的树
if(root1==null){
return root2;
}
if(root2==null){
return root1;
}
root1.val+=root2.val;
root1.left=mergeTrees(root1.left,root2.left);
root1.right=mergeTrees(root1.right,root2.right);
return root1;
}
}
700.二叉搜索树中的搜索
思路
二叉搜索树的特点:所有左子树的值都比根节点值小;所有右子树的值比根节点大。
要按照二叉搜索树的性质来对要搜索的树进行定位再找;首先判断当当前遍历到的节点值等于待搜索节点时,就返回;若不是,需要判断当待搜索值小于根节点,那就在左子树去找;若大于去右子树去找。
注意
当涉及到“二叉搜索树”的题目时,一定要记得利用它本身带有的特点来解题。
实现代码
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.验证二叉搜索树
思路
要验证二叉搜索树,就是按照它的值特点来判断;
根节点值大于所有左子树,小于所有右子树;那么可以用“中序遍历”中序遍历是:左中右,也就意味着搜索到的节点是递增的;
第一种方法:可以选择将按照中序遍历的值放入数组中,然后证明这个数组是递增序列;
第二种方法:设置指向上一个节点的pre指针,pre指针指向上一节点,要与当前节点进行比较,若pre指针指向值大于等于当前节点值,就返回false;反之将当前节点值赋值给pre,然后又继续去遍历下一个节点。
注意
(1)要按照中序遍历!!!
(2)注意指针的赋值方法,之后会用到;
实现代码
//涉及到二叉搜索树,要想起“中序遍历”,得到递增的节点情况
class Solution {
TreeNode pre;//设置上一个指针用来存放上一个节点的值
public boolean isValidBST(TreeNode root) {
if(root==null){
return true;
}
//左
boolean left=isValidBST(root.left);
if(!left){
return false;
}
//中
if(pre!=null&&pre.val>=root.val){
return false;
}else{
pre=root;//为pre指针赋的上一个节点值
}
//右
boolean right=isValidBST(root.right);
return right;
}
}
总结
1.要注意“二叉搜索树”:二叉搜索树的根节点值大于所有左子树,小于所有右子树,完成题目要想到此特点;根据此特点,在对二叉搜索树进行遍历时要用“中序遍历”。
2.当涉及到构造二叉树时,要用“前序遍历”。