代码随想录算法训练营Day20|二叉树part07

53 阅读3分钟

LeetCode 235 二叉搜索树的最近公共祖先

题目链接:leetcode.cn/problems/lo…

文档讲解:programmercarl.com/0235.二叉搜索树的…

视频讲解:www.bilibili.com/video/BV1Zt…

思路

首先可以想到p和q 的最近公共祖先的值一定存在于区间[p,q]中。

假设一个值在[p,q]区间内的节点的值为x,这个节点的左子树的值一定小于x,那么其中一定没有q。同理右子树中一定没有p。那么这个节点的以下都不会有p和q的公共祖先,而根据搜索树性质,这个节点以上的又一定不在此区间内。所以,对二叉搜索树从上往下遍历,遇到的第一个值在[p,q]区间内的节点就是p和q的最近公共祖先。

那么具体如何遍历呢? 考虑搜索树性质,一个节点要么在区间内,要么区间左,要么区间右。所以只需要对在区间内的节点进行搜索,而不需要全部遍历。

解法

class Solution {
	public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {	
		int left = Math.min(p.val, q.val);		
		int right = Math.max(p.val, q.val);				  
		
		while (root != null) {		
			if (root.val < left) {			
				root = root.right;			
			}			
			else if (root.val > right) {			
				root = root.left;			
			}			
			else {			
				return root;			
			}			
		}		
		return null;	
	}
}

LeetCode 701 二叉搜索树中的插入操作

题目链接:leetcode.cn/problems/in…

文档讲解:programmercarl.com/0701.二叉搜索树中…

视频讲解:www.bilibili.com/video/BV1Et…

思路

在搜索树中搜索值val,由于树中没有这个节点,最后一定会落在一个空节点。只需要把新建节点放在这个空节点的位置即可。

解法

class Solution {
	public TreeNode insertIntoBST(TreeNode root, int val) {	
		if (root == null) {		
			return new TreeNode(val);		
		}		
		TreeNode prev = null;		
		TreeNode node = root;		
		while (node != null) {		
			prev = node;			
			if (val > node.val) {			
				node = node.right;				
			}			
			else if (val < node.val) {			
				node = node.left;			
			}			
		}		
		node = new TreeNode(val);		
		if (val > prev.val) {		
			prev.right = node;		
		}		
		else {		
			prev.left = node;		
		}		
		return root;	
	}
}

LeetCode 450 删除二叉搜索树中的节点

题目链接:leetcode.cn/problems/de…

文档讲解:programmercarl.com/0450.删除二叉搜索…

视频讲解:www.bilibili.com/video/BV1tP…

思路

考虑递归三要素:

  1. 递归函数的参数和返回值 参数:根节点,目标key 返回值:删除节点后的根节点
  2. 递归函数的结束条件 如果根节点为空,返回根节点
  3. 单层递归逻辑 如果根节点不是要删除的节点,递归寻找要删除的节点,返回值赋给根节点对应的左右孩子 找到要删除的节点后,有以下几种情况:
    1. 左右孩子都为空,返回空
    2. 左孩子为空,右孩子不为空,返回右孩子
    3. 右孩子为空,左孩子不为空,返回左孩子
    4. 左右孩子都不为空,则把左子树根节点放置在右子树的最左节点的左孩子位置(因为左子树全部小于右子树),返回右孩子

解法

class Solution {
	public TreeNode deleteNode(TreeNode root, int key) {	
		if (root == null) {		
			return root;		
		}		
		if (key < root.val) {		
			root.left = deleteNode(root.left, key);		
		}		
		else if (key > root.val) {		
			root.right = deleteNode(root.right, key);		
		}		
		else {		
			if (root.left == null && root.right == null) {			
				return null;			
			}			
			else if (root.left == null && root.right != null) {			
				return root.right;			
			}			
			else if (root.left != null && root.right == null) {			
				return root.left;			
			}			
			else {			
				TreeNode mostLeft = root.right;				
				while (mostLeft.left != null) {				
					mostLeft = mostLeft.left;				
				}				
				mostLeft.left = root.left;				
				return root.right;			
			}			
		}		
		return root;	
	}
}

今日收获总结

今日学习三小时,二叉搜索树的操作需要很细致的考虑!