530.二叉搜索树的最小绝对值
思路
二叉搜索树的特点:根节点的值大于所有左子树的值,小于所有右子树的值;按照此特点采用中序遍历,获得的值是一直递增的;
本题是要获得相邻节点差值的最小绝对值,按照“中序遍历”,后一个节点值一定是比上一个节点值大的;所以可以使用双指针法,设置一个pre指针指向上一节点,与当前节点值相减,因为当前节点肯定大于上一个节点值,所以相减的差值一定是正数,就不用额外的Math类的abs方法了;在取得最小值后,要给pre节点赋值,又继续开始下一轮直到结束找到最小的绝对值。
注意
使用“双指针法”,记得要给pre节点赋值!!!
实现代码
//使用双指针法
class Solution {
TreeNode pre;
int res=Integer.MAX_VALUE;
public int getMinimumDifference(TreeNode root) {
getMin(root);
return res;
}
public void getMin(TreeNode root){
if(root==null){
return;
}
//左
getMin(root.left);
//中
if(pre!=null&&pre.val<root.val){
res=Math.min(res,root.val-pre.val);
}
pre=root;
//右
getMin(root.right);
}
}
501.二叉搜索树中的众数
思路
“双指针法”
二叉搜索树的特点:根节点的值大于所有左子树的值,小于所有右子树的值;
按照“中序遍历”,获得的节点值是递增的,那么就是说:相同的节点值都是排在一起的。
需要的变量:
- 指向上一节点的指针pre
- 存放出现频率高的节点值的集合list
- 统计当前节点值出现次数的count
- 出现次数最多的maxcount
首先是找到结束的条件,然后注意要中序遍历;对中的处理是:首先当pre指针不为空时指向的节点值1.若与当前节点值相同,统计出现次数的变量count++,统计频率;2.若不相同,说明节点值不同,那么此节点值只出现一次,即count=1;然后判断当前的maxcount是否最大,与count比较,若count>maxcount,那么说明出现了频率更大的节点值,要将原来集合里面存放的节点值clear()清除完全,再将当前出现频率最高的节点值加入集合,最后给maxcount赋值为count;另外一个可能是maxcount=count,那么直接就将这个count对应的节点值加入到集合中;最后的最后千万不要忘记给pre指针赋值。
注意
1.说到count=maxcount时,直接将对应的节点值加入集合中是因为:众数不一定只有一个,可以有多个。
2.注意判断count=1时的条件,一个是pre指针指向节点值不等于当前节点值,另外一个是当pre指针为空时!!!
实现代码
//双指针法
class Solution {
List<Integer> list;
TreeNode pre;
int maxcount;
int count;
public int[] findMode(TreeNode root) {
list=new ArrayList<>();
pre=null;
count=0;
maxcount=0;
getMax(root);
int [] arr=new int[list.size()];
for(int i=0;i<list.size();i++){
arr[i]=list.get(i);
}
return arr;
}
public void getMax(TreeNode root){
if(root==null){
return;
}
getMax(root.left);
//此判断要注意
if(pre==null||pre.val!=root.val){
count=1;
}else{
count++;
}
if(count>maxcount){
list.clear();
list.add(root.val);
maxcount=count;
}else if(count==maxcount){
list.add(root.val);
}
pre=root;
getMax(root.right);
}
}
236.二叉树的最近公共祖先(二刷重点关注题目)
此题可以理解过程,但是代码实现过程没有办法写出来,所有思路不清晰,二刷再注意再再理解!!!
思路
两个节点要找祖父就是按照从下往上反馈,也就是需要“后序遍历”!!!
然后当遍历到要求的两个节点时,需要返回他们的根节点,这就需要涉及到回溯,然后一层层往上回溯将这个祖父返回到根节点获得。
使用后序遍历时获得当前节点的左右节点递归出的结果,然后对这获得的节点进行判断确定返回值。
注意
涉及到“回溯”!!!
实现代码
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null){
return null;
}
//当当前节点遍历到p或q时,返回他们的父节点,要从下往上:回溯
if(root==p||root==q){
return root;
}
//因为要找到p/q,返回他们共同的最近祖先,所以是从下往上反馈就是后序遍历
//左
TreeNode left=lowestCommonAncestor(root.left,p,q);
//右
TreeNode right=lowestCommonAncestor(root.right,p,q);
//中
if(left==null&&right==null){
return null;
}else if(left==null&&right!=null){
return right;
}else if(left!=null&&right==null){
return left;
}else{
return root;
}
}
}
总结
1.二叉搜索的特点一定要用,关于值关于遍历都要记得;
2.关于二叉树的最近公共祖先问题,可以理解整个流程,但是在用代码实现的能力还不够,二刷需要额外关注此题。
3.从开始一直说的递归三部曲,首先找到结束的条件;然后是单层逻辑;最后是递归(按照怎么样的顺序呢?);今天对这递归三部曲比较能理解和按照这个流程了。
4.关于变量的问题,是需要是公共变量还是局部变量就可以了,今天在变量上面犯难了,后序需要研究一下这个问题。