前序和中序可以唯一确定一棵二叉树,后序和中序可以唯一确定一棵二叉树,而前序和后序不能确定一棵二叉树。
有个问题没解决:
class Solution {Map map=new HashMap<>();public TreeNode buildTree(int[] inorder, int[] postorder) {for(int i=0;imap.put(inorder[i],i);}return FindNode(inorder,0,inorder.length,postorder,0,postorder.length);}public TreeNode FindNode(int[] inorder,int inBegin,int inEnd,int[] postorder,int postBegin,int postEnd){if(inBegin>=inEnd||postBegin>=postEnd){return null;}int index=map.get(postorder[postEnd-1]);//int index=map.get(postorder[postorder.length-1]);这样写报错了,但是不知道为啥TreeNode root=new TreeNode(inorder[index]);int leftlength=index-inBegin;root.left=FindNode(inorder,inBegin,index,postorder,postBegin,postBegin+leftlength);root.right=FindNode(inorder,index+1,inEnd,postorder,postBegin+leftlength,postEnd-1);return root;}
}
在代码中注释的那部分出现了错误,报错是:(没解决……)
这道题的map这里,get方法得到的是key对应的value值,所以在前面是把结点的值作为key,把坐标作为value
class Solution {Map map=new HashMap<>();public TreeNode buildTree(int[] preorder, int[] inorder) {for(int i=0;imap.put(inorder[i],i);}return FindNode(preorder,0,preorder.length,inorder,0,inorder.length);}public TreeNode FindNode(int[] preorder,int preBegin,int preEnd,int[] inorder,int inBegin,int inEnd){if(preBegin>=preEnd||inBegin>=inEnd){return null;}int index=map.get(preorder[preBegin]);TreeNode root=new TreeNode(inorder[index]);int leftlen=index-inBegin;root.left=FindNode(preorder,preBegin+1,preBegin+1+leftlen,inorder,inBegin,index);root.right=FindNode(preorder,preBegin+1+leftlen,preEnd,inorder,index+1,inEnd);return root;}
}
感觉这个题特别难,但是看了答案发现,和其前面的两个题很像,只不过这道题的根节点是找最大值作为根节点,然后由根节点将数组分成左右两部分,也就是左右子树,相当于把前面的题的其中一个遍历序列隐藏了,但是思路仍然是一样的。仍然还需要两个指针,只是得到根节点的方法比较简单
class Solution {public TreeNode constructMaximumBinaryTree(int[] nums) {return BuildTree(nums,0,nums.length);}public TreeNode BuildTree(int[] nums,int leftIndex,int rigthIndex){if(rigthIndex-leftIndex<1){return null;}if(rigthIndex-leftIndex==1){return new TreeNode(nums[leftIndex]);}int maxIndex=leftIndex;int maxValue=nums[maxIndex];for(int i=leftIndex+1;i//if(maxValuemaxIndex=i;maxValue=nums[i];}}TreeNode root=new TreeNode(maxValue);root.left=BuildTree(nums,leftIndex,maxIndex);root.right=BuildTree(nums,maxIndex+1,rigthIndex);return root;}
}
递归:
class Solution {public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {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;}
}
非递归:
class Solution {public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {if(root1==null) return root2;if(root2==null) return root1;Stack stack=new Stack<>();stack.push(root2);stack.push(root1);while(!stack.isEmpty()){TreeNode node1=stack.pop();TreeNode node2=stack.pop();node1.val+=node2.val;if(node1.right!=null&&node2.right!=null){stack.push(node2.right);stack.push(node1.right);}if(node1.right==null&&node2.right!=null){node1.right=node2.right;}if(node1.left!=null&&node2.left!=null){stack.push(node2.left);stack.push(node1.left);}if(node1.left==null&&node2.left!=null){node1.left=node2.left;}}return root1;}
}
注意:
1、这道题还可以用队列的方式,队列的话,就不用先让右子树入队,然后再让左子树入队了
2、再说一遍:栈的方法是——push、pop,队列的出入方法是——offer、poll
3、还有判空的方法是stack.isEmpty()别写错了
递归:(但是没有用到二叉搜索树的特点)
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;TreeNode right=searchBST(root.right,val);return right;}
}
这里要注意,不能写成:return searchBST(root.left,val);和return searchBST(root.right,val);因为要等到所有节点都遍历完之后再返回,否则下面的搜索右子树的语句永远不会执行。他执行的前提是左子树没有搜索到节点,所以需要判断左子树是否搜索到了!
递归:(用到二叉搜索树的特点)
public TreeNode searchBST(TreeNode root, int val) {if(root==null||root.val==val){return root;}if(root.val
非递归:
public TreeNode searchBST(TreeNode root, int val) {while(root!=null){if(root.val==val) return root;else if(root.val
这里要注意:while中的if判断不能写成三个if并列,因为他们每次都要先对root是否为空进行判断,之后再循环。如果是并列的,那不会先执行while的条件,所以有可能root就是null,那root.left或root.right就可能会报空指针异常!
把这道题想简单了,不能只是判断节点和其根节点的关系是否满足左小右大,还要保证节点和其祖先节点也满足这种关系……
还要注意:
1、这个题的结点的值的取值范围是:-2^31 <= Node.val <= 2^31 - 1,所以如果是int类型,不能
2、空树也是二叉搜索树,即二叉搜索树也可以为空!
3、二叉搜索树中的节点值是不能重复的
递归:
class Solution {public boolean isValidBST(TreeNode root) {return validBST(Long.MIN_VALUE,Long.MAX_VALUE, root);}public boolean validBST(long lower,long upper,TreeNode root){if(root==null) return true;if(root.val<=lower||root.val>=upper) return false;return validBST(lower,root.val,root.left)&&validBST(root.val,upper,root.right);}
}
中序遍历:
class Solution {long prev=Long.MIN_VALUE;public boolean isValidBST(TreeNode root) {if(root==null) return true;if(!isValidBST(root.left)){return false;}if(root.val<=prev) return false;prev=root.val;return isValidBST(root.right);}
}
这里要注意root.val和prev进行判断以及修改prev的值的位置,如果在左子树遍历之前,
答案:因为二叉搜索树中的节点值不能重复,基于其特性,中序遍历一个二叉搜索树会是一个自增的数组,所以最小的差值肯定是在两个相邻的节点间产生,不可能是隔了一个节点或者更多的节点,因为只要中间隔了节点,那这两个节点的差值一定就比相邻的两个结点的差值要大。比如:x、y、z三个节点,不可能说,x和z之间的差值比yz之间的差值小,因为遍历后的结果是x 递归: 中序遍历: 这道题有可能出现多个众数,就需要把多个众数都放进数组里。正常的方法可能会遍历两边数组,一次是找最大的出现频率,一次是找出现频率=最大出现频率的所有数并存储进结果数组中。 leetcode的官方题解的另一种空间复杂度为O(1)的方法我没看懂,首推了一遍感觉例子上的树会返回1和2啊?????哎…… 答案真的简单到可怕哎…… 如果两个节点都在同一颗子树中,而且一个结点的层数比另一个节点的高(也就是其中一个节点是另一个节点的祖先节点或父节点),那么在递归的过程中,会先找到这个祖先节点,根据递归的写法,此时会直接返回,不会在这颗子树再找另一个节点。所以如果遍历另外一棵子树,返回结果是null。但是因为题目中已经告诉了两个节点一定存在,所以不用担心只找到了祖先节点就返回,另一个节点没找到的情况。 平衡二叉树与完全二叉树的区别在于底层节点的位置? 堆是完全二叉树和排序的结合,而不是平衡二叉搜索树?class Solution {TreeNode pre;int min=Integer.MAX_VALUE;public int getMinimumDifference(TreeNode root) {if(root==null) return 0;traversal(root);return min;}public void traversal(TreeNode root){if(root==null) return;traversal(root.left);if(pre!=null){min=Math.min(min,root.val-pre.val);}pre=root;traversal(root.right);}
}
class Solution {TreeNode pre;Stack
501. 二叉搜索树中的众数
但是也可以通过遍历一次数组,思路是,在出现频率=最大出现频率时,将对应的书加入结果数组,如果出现了 出现频率>最大出现频率的情况,不仅要更改最大出现频率对应的数据,还要先清空结果数组并将这个结果加入结果数组。
而且其实相同的书肯定在遍历得到的中序数组中是挨着的class Solution {List
236. 二叉树的最近公共祖先
class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root==null||root==p||root==q){return root;}TreeNode left=lowestCommonAncestor(root.left,p,q);TreeNode right=lowestCommonAncestor(root.right,p,q);if(left==null&&right==null) return null;else if(left==null&&right!=null) return right;else if(left!=null&&right==null) return left;else return root;}
}
补充
是的,完全二叉树底层必须是从左到右连续的,且次底层是满的。
堆是一棵完全二叉树,同时保证父子节点的顺序关系(有序)。 但完全二叉树一定是平衡二叉树,堆的排序是父节点大于子节点,而搜索树是父节点大于左孩子,小于右孩子,所以堆不是平衡二叉搜索树。
上一篇:Mybatis报BindingException:Invalid bound statement (not found)异常
下一篇:我驻美使馆:已提出严正交涉;美上诉法院恢复实施特朗普政府关税政策;美联邦法官叫停“哈佛禁令” 我驻美使馆:已提出严正交涉;美上诉法院恢复实施特朗普政府关税政策;美联邦法官叫停“哈佛禁令”