代码随想录算法训练营第21天 | 236. 二叉树的最近公共祖先,501. 二叉搜索树中的众数,530. 二叉搜索树的最小绝对差
530. 二叉搜索树的最小绝对差
- 二叉搜索树是有序的 中序遍历把节点值从小到大可以放到数组中 然后遍历 求最小绝对差值
class Solution {
List<Integer> arr = new ArrayList<>();
public int getMinimumDifference(TreeNode root) {
int res = Integer.MAX_VALUE;
traversal(root);
for(int i =1;i<arr.size();i++){
res = Math.min(res,arr.get(i)-arr.get(i-1));
}
return res;
}
public void traversal(TreeNode node){
if(node==null) return;
traversal(node.left);
arr.add(node.val);
traversal(node.right);
return;
}
}
用双指针来遍历 求差值
class Solution {
int res = Integer.MAX_VALUE;
TreeNode pre = null;
public int getMinimumDifference(TreeNode root) {
traversal(root);
return res;
}
public void traversal(TreeNode cur){
if(cur==null) return;
traversal(cur.left);
if(pre!=null){
res = Math.min(res,cur.val-pre.val);
}
pre = cur;
traversal(cur.right);
return;
}
}
501. 二叉搜索树中的众数
- 将重复值出现次数存入map 求出最多次数的 对应值
import java.util.Collection;
class Solution {
Map<Integer,Integer> map = new HashMap<>();
public int[] findMode(TreeNode root) {
traversal(root);
Collection<Integer> valuelist = map.values();
int max = 0;
for(Integer num:valuelist){
max = Math.max(max,num);
}
return getKey(max);
}
public void traversal(TreeNode node){
if(node==null) return;
traversal(node.left);
map.put(node.val,map.getOrDefault(node.val, 0) + 1);
traversal(node.right);
return;
}
public int[] getKey(int value){
List<Integer> res = new ArrayList<>();
for(Integer key: map.keySet()){
if(map.get(key)==value){
res.add(key);
}
}
int[] result = new int[res.size()];
for(int i =0;i<res.size();i++){
result[i]=res.get(i);
}
return result;
}
}
双指针 只遍历一次
- 如何边遍历边将最大次数存入结果 可以设置一个maxcount 当count==maxcount时 存入结果集
- 当count>maxcount时 清空结果集 更新maxcount 存入结果集
class Solution {
int count = 0;
int maxcount = 0;
TreeNode pre = null;
List<Integer> result = new ArrayList<>();
public int[] findMode(TreeNode root) {
traversal(root);
int[] res = new int[result.size()];
for(int i =0;i<result.size();i++){
res[i]=result.get(i);
}
return res;
}
public void traversal(TreeNode cur){
if(cur==null) return;
traversal(cur.left);
if(pre==null){
count=1;
}else if(cur.val==pre.val){
count++;
}else{
count=1;
}
pre=cur;
if(count==maxcount){
result.add(cur.val);
}
if(count>maxcount){
result.clear();
maxcount=count;
result.add(cur.val);
}
traversal(cur.right);
return;
}
}
236. 二叉树的最近公共祖先
- 需要从底部向上查找 用后序遍历 判断左右是否有目标节点 有则往上面返回
- 若遇到 某个父节点 的左右子树的返回值 都不为Null 那么就返回这个父节点root 它就是最小祖先
- 若一直找到底都没有遇到pq 就返回Null回去
- 还有一种可能是 p为q的父节点 这种情况也可以处理 因为只要遇到P或q 就返回该节点
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null) return null;
if(root==p || root==q) return root;
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(left!=null && right!=null){
return root;
}
if(left!=null && right==null) return left;
if(left==null && right!=null) return right;
if(left==null && right==null) return null;
return root;
}
}