654:最大二叉树
和105(利用前序和中序构造二叉树),106(利用中序和后序构造二叉树)类似:
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return build(nums, 0, nums.length);
}
public TreeNode build(int[] nums, int begin, int end) {
if (begin>=end) {
return null;
}
int max = Integer.MIN_VALUE;
int len = -1;
for (int i = begin; i < end; i++) {
if (nums[i]>max) {
max = nums[i];
len = i-begin;
}
}
TreeNode root = new TreeNode(max);
root.left = build(nums, begin, begin+len);
root.right = build(nums, begin+len+1, end);
return root;
}
}
617:合并二叉树
对合并时候可能的情况的进行了分类,如果左右都为空,返回null,如果只有一个为null的话返回另一个,如果都不为空的话返回二者之和。
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1==null && root2==null) {
return null;
}
TreeNode root;
if (root1==null && root2!=null) {
root = new TreeNode(root2.val);
root.left = mergeTrees(null, root2.left);
root.right = mergeTrees(null, root2.right);
}else if (root1!=null && root2==null) {
root = new TreeNode(root1.val);
root.left = mergeTrees(root1.left, null);
root.right = mergeTrees(root1.right, null);
}else {
root = new TreeNode(root1.val+root2.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) {
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;
}
}
迭代法:
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
Queue<TreeNode> queue = new LinkedList<>();
if (root1==null) {
return root2;
}
if (root2==null) {
return root1;
}
queue.offer(root1);
queue.offer(root2);
while (!queue.isEmpty()) {
TreeNode t1 = queue.poll();
TreeNode t2 = queue.poll();
t1.val += t2.val;
if (t1.left!=null && t2.left!=null) {
queue.offer(t1.left);
queue.offer(t2.left);
}
if (t1.right!=null && t2.right!=null) {
queue.offer(t1.right);
queue.offer(t2.right);
}
if (t1.left==null && t2.left!=null) {
t1.left = t2.left;
}
if (t1.right==null && t2.right!=null) {
t1.right = t2.right;
}
}
return root1;
}
}
700:二叉搜索树中的搜索
利用好二叉搜索树的性质:
二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
递归:
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if (root==null) {
return null;
}
if (root.val==val) {
return root;
}else if (val<root.val) {
return searchBST(root.left, val);
}else{
return searchBST(root.right, val);
}
}
}
迭代:
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 {
public boolean isValidBST(TreeNode root) {
List<Integer> list = new LinkedList<>();
inorder(root, list);
for (int i = 1; i < list.size(); i++) {
if (list.get(i)<=list.get(i-1)) {
return false;
}
}
return true;
}
public void inorder(TreeNode root, List<Integer> list) {
if (root==null) {
return;
}
if (root.left!=null) {
inorder(root.left, list);
}
list.add(root.val);
if (root.right!=null) {
inorder(root.right, list);
}
}
}
在递归遍历的过程中直接判断,值得注意的是:我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。
定义一个全局max用来记录当前遍历得到的最大值,如果遍历过程中出现比max小的,说明不是二叉搜索树。
class Solution {
long max = Long.MIN_VALUE;;
public boolean isValidBST(TreeNode root) {
return is(root);
}
public boolean is(TreeNode root) {
if (root==null) {
return true;
}
//左
boolean left = is(root.left);
if (!left) {
return false;
}
//中
if (root.val>max) {
max = root.val;
}else {
return false;
}
//右
boolean right = is(root.right);
return right;
}
}
如果记录最大值所在的节点会比记录最大值适用性更强,因为如果测试用例中有long的最小值的话,就会出错。
class Solution {
TreeNode max = null;
public boolean isValidBST(TreeNode root) {
return is(root);
}
public boolean is(TreeNode root) {
if (root==null) {
return true;
}
//左
boolean left = is(root.left);
if (!left) {
return false;
}
//中
if (max==null || (max!=null && root.val>max.val)) {
max = root;
}else {
return false;
}
//右
boolean right = is(root.right);
return right;
}
}
迭代法:基于中序遍历的基础上,用栈来模拟
class Solution {
TreeNode max = null;
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
if (root==null) {
return true;
}
TreeNode maxNode = null;
while (root!=null || !stack.isEmpty()) {
if(root!=null) {
stack.push(root);
root = root.left;
}else {
root = stack.pop();
if (maxNode==null || (root.val>maxNode.val)) {
maxNode = root;
}else {
return false;
}
root = root.right;
}
}
return true;
}
}
总结:总的来说,对递归方法更熟悉了。验证二叉搜索树确实陷进很深,不注意的话很难找到错误。