leetcode-zgd-day21-530.二叉搜索树的最小绝对差/501.二叉搜索树中的众数/236.二叉树的最近公共祖先

69 阅读1分钟

530.二叉搜索树的最小绝对差

题目链接:Loading Question... - 力扣(LeetCode)

解题思路:

首先通过层序遍历把二叉树转换成数组,再对数组进行排序,然后再遍历数组确定最小差值

 class Solution {
     public int getMinimumDifference(TreeNode root) {
         // 层序遍历先保存一个数组,然后数组排序,然后计算最小差值
         List<Integer> record = changeList(root);
         Collections.sort(record);
         int min = Integer.MAX_VALUE;
         for(int i = 1; i < record.size(); i++){
             min = min > record.get(i) - record.get(i - 1) ? record.get(i) - record.get(i - 1) : min;
         }
         return min;
     }
     List<Integer> changeList(TreeNode root){
         List<Integer> record = new ArrayList<>();
         if(root == null) return record;
         Queue<TreeNode> que = new LinkedList<>();
         que.offer(root);
         while(!que.isEmpty()){
             TreeNode cur = que.poll();
             record.add(cur.val);
             if(cur.left != null) que.offer(cur.left);
             if(cur.right != null) que.offer(cur.right);
         }
         return record;
     }
 }

上面的题解存在一个巨大的问题就是,没有注意到一个前提,这个树是二叉搜索树,按照中序遍历的话是有序的。所以可以直接中序遍历。

 class Solution {
     TreeNode pre;// 记录上一个遍历的结点
     int result = Integer.MAX_VALUE;
     public int getMinimumDifference(TreeNode root) {
        if(root==null)return 0;
        traversal(root);
        return result;
     }
     public void traversal(TreeNode root){
         if(root==null)return;
         //左
         traversal(root.left);
         //中
         if(pre!=null){
             result = Math.min(result,root.val-pre.val);
         }
         pre = root;
         //右
         traversal(root.right);
     }
 }

501.二叉搜索树中的众数

题目链接:Loading Question... - 力扣(LeetCode)

解题思路:

遍历二叉树,将二叉树中节点值的频次保存成一个map,按照map的value值进行排序。然后判断有多少个键值对的value都是最大值,将他们转存入List,再通过流操作将Integer的List转换成int[]

 class Solution {
     public int[] findMode(TreeNode root) {
         List<Integer> ans = new LinkedList<>();
         List<Map.Entry<Integer,Integer>> record = changeMap(root);
         int max = record.get(0).getValue();
         for(int i = 0; i < record.size(); i++){
             if(max == record.get(i).getValue()) ans.add(record.get(i).getKey());
             else{
                 break;
             }
         }
         return ans.stream().mapToInt(Integer::intValue).toArray();
     }
     List<Map.Entry<Integer,Integer>> changeMap(TreeNode root){
         Map<Integer,Integer> record = new HashMap<>();
         List<Map.Entry<Integer,Integer>> list = new ArrayList<>();
         if(root == null) return list;
         Queue<TreeNode> que = new LinkedList<>();
         que.offer(root);
         while(!que.isEmpty()){
             TreeNode cur = que.poll();
             if(record.containsKey(cur.val)){
                 record.put(cur.val,record.get(cur.val) + 1);
             }else{
                 record.put(cur.val,1);
             }
             if(cur.left != null) que.offer(cur.left);
             if(cur.right != null) que.offer(cur.right);
         }
         list = new ArrayList(record.entrySet());
         Collections.sort(list, (o1, o2) -> (o2.getValue() - o1.getValue()));
         return list;
     }
 }

236.二叉树的最近公共祖先

题目链接:Loading Question... - 力扣(LeetCode)

解题思路:

递归法:

首先要明确,我们想要自底向上的遍历,所以就需要采用后序遍历的方式,后序遍历是天然的自底向上的遍历方式。

确定函数的结束条件和返回值,函数的返回值就是p或者q或者null,如果p在以root为根的树上,就返回p,同理如果q在以root为根的树上,就返回q。

结束条件是:根节点是p或者q或者为空,直接结束。

如果左子树右子树一个返回p一个返回q,代表root就是公共最近祖先。return root

如果只有某一个子树不为空,直接返回这个子树返回的节点即可。

 class Solution {
     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
         // 回溯法
         if(root == q || root == p || root == null) return root;
         TreeNode lefthas = lowestCommonAncestor(root.left,p,q);
         TreeNode righthas = lowestCommonAncestor(root.right,p,q);
         if(lefthas != null && righthas != null) return root;
         if(lefthas == null && righthas != null) return righthas;
         else if(lefthas != null && righthas == null) return lefthas;
         else{
             return null;
         }
     }
 }