代码随想录第20天:654.最大二叉树、617.合并二叉树 、700.二叉搜索树中的搜索 、98.验证二叉搜索树

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;
    }

}

总结:总的来说,对递归方法更熟悉了。验证二叉搜索树确实陷进很深,不注意的话很难找到错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值