654 最大二叉树
https://leetcode.cn/problems/maximum-binary-tree/
class Solution { // TO(n^2) SO(height)
public TreeNode constructMaximumBinaryTree(int[] nums) {
return build(nums, 0, nums.length - 1);
}
private TreeNode build(int[] nums, int leftIndex, int rightIndex) {
if (leftIndex > rightIndex) return null;
int maxIndex = leftIndex, maxValue = nums[leftIndex];
for (int i = leftIndex + 1; i <= rightIndex; i++) { // bug, i <= rightIndex 不是 i< rightIndex
if (nums[i] > maxValue) {
maxValue = nums[i];
maxIndex = i;
}
}
TreeNode root = new TreeNode(maxValue);
root.left = build(nums, leftIndex, maxIndex - 1);
root.right = build(nums, maxIndex + 1, rightIndex);
return root;
}
}
单调递减栈做法可以做到TO(n), 从左向右遍历,栈里存子树已经全部挂好的根节点,这个栈是单调递减的,来一个新节点时,栈里比它小的要全部出队挂到它的左子树,同时出队过程中,先出的节点要挂在后出的节点的右子树上,遍历到最后虚拟一个比所有节点都大的值,情空栈。
class Solution { //TO(n)
public TreeNode constructMaximumBinaryTree(int[] nums) {
Deque<TreeNode> stack = new ArrayDeque<>();
for (int i = 0; i <= nums.length; i++) {
TreeNode next = new TreeNode(i == nums.length ? nums.length : nums[i]); //数组最后虚拟一个最大值,可以自动清空栈
TreeNode cur = null;
while (!stack.isEmpty() && stack.peekFirst().val <= next.val) { //来的比前面的大,拿出来挂左子树
TreeNode pre = stack.pollFirst(); //拿的过程中依次挂在下一个node的右子树上
pre.right = cur;
cur = pre;
}
next.left = cur; //最后一个比next小的是她的左子树
stack.offerFirst(next);
}
return stack.pollFirst().left;
}
}
617合并二叉树
https://leetcode.cn/problems/merge-two-binary-trees/
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null) return root2;
if (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 二叉搜索树中的搜索
https://leetcode.cn/problems/search-in-a-binary-search-tree/
递归和迭代
class Solution { //recursive
public TreeNode searchBST(TreeNode root, int val) {
if (root == null || root.val == val) return root;
if (root.val > val) return searchBST(root.left, val);
return searchBST(root.right, val);
}
}
class Solution { //iterative
public TreeNode searchBST(TreeNode root, int val) {
while (root != null) {
if (root.val == val) {
return root;
} else if (root.val > val) {
root = root.left;
} else {
root = root.right;
}
}
return null;
}
}
98 验证二叉搜索树
https://leetcode.cn/problems/validate-binary-search-tree/ 三种方法
class Solution { //方法1,由上向下传值表示合理range
public boolean isValidBST(TreeNode root) {
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
private boolean isValidBST(TreeNode root, long min, long max) {
if (root == null) return true;
if (root.val >= max || root.val <= min) return false;
return isValidBST(root.left, min, root.val) && isValidBST(root.right, root.val, max);
}
}
class Solution { //方法2,由下向上传range
public boolean isValidBST(TreeNode root) {
return getRange(root)[0] != Long.MIN_VALUE;
}
private long[] getRange(TreeNode root) {
if (root == null) return new long[]{Long.MAX_VALUE, Long.MIN_VALUE};
long[] leftRange = getRange(root.left);
long[] rightRange = getRange(root.right);
if (root.val <= leftRange[1] || root.val >= rightRange[0]) return new long[]{Long.MIN_VALUE, Long.MAX_VALUE};
// if (root.left == null) leftRange[0] = root.val; //关键是在形成新的range时要把不valid的null的返回值排除掉
// if (root.right == null) rightRange[1] = root.val;
// return new long[]{leftRange[0], rightRange[1]};
// 以上三行也可写成
return new long[]{Math.min(leftRange[0], root.val), Math.max(rightRange[1], root.val)};
}
}
class Solution { //方法3,中序遍历记录前值,边遍历边比较
public boolean isValidBST(TreeNode root) {
Integer[] pre = new Integer[]{null};
return check(root, pre);
}
private boolean check(TreeNode root, Integer[] pre) {
if (root == null) return true;
if (!check(root.left, pre)) return false;
if (pre[0] != null && pre[0] >= root.val) return false;
pre[0] = root.val;
return check(root.right, pre);
}
}