235:
不是很难的一道题,重点是要熟练掌握BST(二叉搜索树)的特性。
如果pq都比当前节点大,那就只搜索右子树,如果都小,则只搜索左子树,如果一个大一个小则代表找到了最小公共祖先。
701:
不改变树的结构的话这道题也不是很难。通过有返回值的递归来做的话需要重点理解:
当新节点插入后开始返回时,实际上相当于是把新节点的信息返回给父节点的左/右指针,这样一来相当于是把新节点和原树连接上了。
在插入完成后,要把树的原始节点原封不动的一层层返回回去,直接return递归方程里的TreeNode变量就好了。
450:
一下子难度就来了,而且这种通过返回值直接更新节点左右指针来达成目的的方法还需要更多理解和练习。一开始自己写的处理四种不复杂情况的代码还是拘泥于迭代遍历时的更新方法,类似于这种: previous.left = current.left 。
但其实这道题和上一道实现增加/删除的方法是一样的,通过返回值来更新根节点的左右指针来达成操作。
这道题最重要的是理解最复杂的情况(要删除的节点的左右子节点都不为空)的解法:
根据二叉搜索树的特性,要删除的节点的左子树里的所有元素都比它小,右子树里所有元素都比它大。
删除目标节点后,我们需要找到一个比所有左子树元素大的节点,然后把左子树更新成这个节点的左子树,这个节点只能是目标节点右子树中的最小节点(右子树的最左下角)。
我们通过迭代遍历的方式找到这个节点,然后把左子树接到这个节点的左子树上。
然后,我们直接将目标节点的右子树接到目标节点的父节点上,删除+保持二叉搜索树特性的操作就做完了。我们最后还需要一层层把递归返回上去。
以上的操作镜像翻转一下也可以成立(把目标节点的右子树挪到左子树的最大节点的下面)。