代码随想录算法训练营第20天|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
一. 二叉树相关算法题
654.最大二叉树
思路
- 查找最大值以及所在下标
- 通过最大值下标拆分左右序列
- 通过左右序列构造左右子树
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return getTreeNode(nums,0, nums.length);
}
//左闭右开不要使用最后一个下标
public TreeNode getTreeNode(int[] nums, int start, int end) {
//递归终止条件
if (start==end) return null;
//查找最大值
int maxValue = nums[start];
int maxIndex = start;
for (int i = start+1; i < end; i++) {
if (maxValue<nums[i]){
maxValue = nums[i];
maxIndex = i;
}
}
TreeNode treeNode = new TreeNode(maxValue);
//拆分左右子序列
int subLeftStart = start;
int subLeftEnd = maxIndex;
//构建左子树
treeNode.left = getTreeNode(nums,subLeftStart,subLeftEnd);
int subRighttStart = maxIndex+1;
int subRighhtEnd = end;
//构建右子树
treeNode.right = getTreeNode(nums,subRighttStart,subRighhtEnd);
return treeNode;
}
}
617.合并二叉树
思路
- 递归合并两个树的左右节点
- 如果遇到都为空直接返回
- 如果其中一个为空直接返回不为空的
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
//递归终止条件
if (root1 == null && root2 == null) return null;
if (root1 == null && root2 != null) return root2;
if (root1 != null && root2 == null) return root1;
//单层递归逻辑
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.二叉搜索树中的搜索
递归
搜索
- 根据二叉搜索树的特性左>根>右可以写出如下递归逻辑
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
//递归终止条件
if (root == null) return null;
if (root.val>val){
return searchBST(root.left,val);
} else if (root.val<val) {
return searchBST(root.right,val);
}else {
return root;
}
}
}
迭代
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
while (root != null) {
if (root.val > val) {
root = root.left;
} else if (root.val < val) {
root = root.right;
} else {
return root;
}
}
return null;
}
}
98.验证二叉搜索树
对于二叉搜索树的题优先考虑中序遍历
判断序列是否从小到大
思路
- 先中序遍历将二叉树存储到序列中然后判断序列是否从小到达排列
class Solution {
List<Integer> list = new ArrayList<>();
public boolean isValidBST(TreeNode root) {
//中序遍历输出的搜索树序列为有序的
traversal(root);
for (int i = 1; i < list.size(); i++) {
if (list.get(i)<= list.get(i-1)) return false;
}
return true;
}
public void traversal(TreeNode treeNode) {
if (treeNode == null) return;
//左
traversal(treeNode.left);
//中
list.add(treeNode.val);
//右
traversal(treeNode.right);
}
}
在递归中判断是否有序
思路
- 中序遍历判断前一个节点是否小于后一个节点
- 陷阱:
- 搜索二叉树的根节点小于右子树的所有节点,大于左子树的所有节点
class Solution {
TreeNode pre = null;
public boolean isValidBST(TreeNode root) {
//递归终止条件
if (root == null) return true;
//左
boolean left = isValidBST(root.left);
//中
if (pre!=null && pre.val>=root.val) return false;
pre = root;
//右
boolean right = isValidBST(root.right);
return left&&right;
}
}