LeetCode 654 最大二叉树
题目链接:最大二叉树
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。
示例 1:
输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
- [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
- 空数组,无子节点。
- [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
- 空数组,无子节点。
- 只有一个元素,所以子节点是一个值为 1 的节点。
- [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
- 只有一个元素,所以子节点是一个值为 0 的节点。
- 空数组,无子节点。
示例 2:
输入:nums = [3,2,1]
输出:[3,null,2,null,1]
这个题和昨天根据中序和后序遍历构造二叉树的题递归的方法很相似,都要注意分割左右区间的方式,是左闭右开还是左闭右闭。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
if(nums.length==0)return null;
return build(nums,0,nums.length);
}
public int findMaxIndex(int[] arr,int start,int end){
int Max=arr[start];
int index=start;
for(int i=start+1;i<end;i++){
if(arr[i]>Max){
Max=arr[i];
index=i;
}
}
//System.out.println(Max);
return index;
}
//左闭右开
public TreeNode build(int[] arr,int start,int end){
if(start==end)return null;
int leftstart,leftend,rightstart,rightend;
int index=findMaxIndex(arr,start,end);
TreeNode root=new TreeNode(arr[index]);
leftstart=start;
leftend=index;
rightstart=index+1;
rightend=end;
TreeNode left=build(arr,leftstart,leftend);
TreeNode right=build(arr,rightstart,rightend);
root.left=left;
root.right=right;
return root;
}
}
LeetCode 617 合并二叉树
题目链接:合并二叉树
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
示例 1:
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]
示例 2:输入:root1 = [1], root2 = [1,2]
输出:[2,2]
递归法:
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
//递归
if(root1==null&&root2==null)return null;
if(root1==null)return root2;
if(root2==null)return root1;
int val=(root1==null?0:root1.val)+(root2==null?0:root2.val);
TreeNode root=new TreeNode(val);
root.left=mergeTrees(root1.left,root2.left);
root.right=mergeTrees(root1.right,root2.right);
return root;
}
}
迭代法:
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
//迭代
if(root1==null&&root2==null)return null;
if(root1==null)return root2;
if(root2==null)return root1;
Deque<TreeNode> q=new LinkedList<>();
q.push(root2);
q.push(root1);
while(!q.isEmpty()){
TreeNode tmp1=q.pop();
TreeNode tmp2=q.pop();
tmp1.val+=tmp2.val;
if(tmp1.left!=null&&tmp2.left!=null){
q.push(tmp2.left);
q.push(tmp1.left);
}
if(tmp1.right!=null&&tmp2.right!=null){
q.push(tmp2.right);
q.push(tmp1.right);
}
if(tmp1.left==null&&tmp2.left!=null)tmp1.left=tmp2.left;
if(tmp1.right==null&&tmp2.right!=null)tmp1.right=tmp2.right;
}
return root1;
}
}
LeetCode 700 二叉搜索树中的搜索
题目链接:二叉搜索树中的搜索
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。
示例 1:
输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]
示例 2:
输入:root = [4,2,7,1,3], val = 5
输出:[]
二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
递归法:
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
//递归
if(root==null)return null;
if(root.val==val)return root;
if(root.val>val)return searchBST(root.left,val);
return searchBST(root.right,val);
}
}
迭代法:
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
//迭代
if(root==null||root.val==val)return root;
Stack<TreeNode> st=new Stack<>();
st.push(root);
while(!st.isEmpty()){
TreeNode node=st.pop();
if(node.val>val){
if(node.left!=null)st.push(node.left);
else return null;
}
else if(node.val<val){
if(node.right!=null)st.push(node.right);
else return null;
}
else return node;
}
return null;
}
}
优化,不用栈:
class Solution {
// 迭代,利用二叉搜索树特点,优化,可以不需要栈
public TreeNode searchBST(TreeNode root, int val) {
while (root != null)
if (val < root.val) root = root.left;
else if (val > root.val) root = root.right;
else return root;
return null;
}
}
LeetCode 98 验证二叉搜索树
题目链接:验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
思路:中序遍历二叉树放在链表中,判断链表是否是递增的。直接套模板就行。
递归法:
class Solution {
//递归
public boolean isValidBST(TreeNode root) {
List<Integer> list=inorder(root);
for(int i=0;i<list.size()-1;i++){
if(list.get(i)>=list.get(i+1))return false;
}
return true;
}
public List<Integer> inorder(TreeNode node){
List<Integer> list=new ArrayList<>();
if(node==null)return list;
list.addAll(inorder(node.left));
list.add(node.val);
list.addAll(inorder(node.right));
return list;
}
}
}
也可以这样写,这样更简洁一点:
class Solution {
private 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);
}
}
迭代法:
class Solution {
//迭代
public boolean isValidBST(TreeNode root){
Stack<TreeNode> st=new Stack<>();
List<Integer> list=new ArrayList<>();
if(root!=null)st.push(root);
while(!st.isEmpty()){
TreeNode node=st.pop();
if(node!=null){
if(node.right!=null)st.push(node.right);
st.push(node);
st.push(null);
if(node.left!=null)st.push(node.left);
}
else{
node=st.pop();
list.add(node.val);
}
}
for(int i=0;i<list.size()-1;i++){
if(list.get(i)>=list.get(i+1))return false;
}
return true;
}
}