530.二叉搜索树的最小绝对差
需要领悟一下二叉树遍历上双指针操作,优先掌握递归
题目链接:
文章讲解:代码随想录
视频讲解:二叉搜索树中,需要掌握如何双指针遍历!| LeetCode:530.二叉搜索树的最小绝对差_哔哩哔哩_bilibili
遇到在二叉搜索树上求什么最值,求差值之类的,都要思考一下二叉搜索树可是有序的,要利用好这一特点。
同时要学会在递归遍历的过程中如何记录前后两个指针,这也是一个小技巧,学会了还是很受用的。
二叉搜索树的中序遍历结果是升序的。因为题中要求的是任意两不同节点值之间的最小差值,我们只需要在中序遍历的时候和前一个节点比较,保存最小的差值即可。
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.二叉搜索树中的众数
和 530差不多双指针思路,不过 这里涉及到一个很巧妙的代码技巧。
可以先自己做做看,然后看我的视频讲解。
题目链接:
视频讲解:不仅双指针,还有代码技巧可以惊艳到你! | LeetCode:501.二叉搜索树中的众数_哔哩哔哩_bilibili
按照没有搜索树的条件写的一个找众树:
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); public int[] findMode(TreeNode root) { isEquals(root); List<Integer> list = new ArrayList<>(); PriorityQueue<int[]> pq = new PriorityQueue<>((pair1,pair2)->pair2[1]-pair1[1]); for(Map.Entry<Integer,Integer> entry:map.entrySet()){ if(pq.size()<map.size()){ pq.add(new int[]{entry.getKey(),entry.getValue()}); } System.out.println(pq.peek()[1]); } list.add(pq.peek()[0]); int count = pq.peek()[1]; pq.poll(); while(!pq.isEmpty() && count == pq.peek()[1]){ list.add( pq.peek()[0]); pq.poll(); } int[] arr = new int[list.size()]; for (int i = 0; i < list.size(); i++) { arr[i] = list.get(i); } return arr; } public void isEquals(TreeNode root){ if(root == null){ return; } map.put(root.val , map.getOrDefault(root.val,0)+1); isEquals(root.right); isEquals(root.left); }
public int[] findMode(TreeNode root) { Map<Integer, Integer> map = new HashMap<>(); List<Integer> list = new ArrayList<>(); if (root == null) return list.stream().mapToInt(Integer::intValue).toArray(); // 获得频率 Map searchBST(root, map); List<Map.Entry<Integer, Integer>> mapList = map.entrySet().stream() .sorted((c1, c2) -> c2.getValue().compareTo(c1.getValue())) .collect(Collectors.toList()); list.add(mapList.get(0).getKey()); // 把频率最高的加入 list for (int i = 1; i < mapList.size(); i++) { if (mapList.get(i).getValue() == mapList.get(i - 1).getValue()) { list.add(mapList.get(i).getKey()); } else { break; } } return list.stream().mapToInt(Integer::intValue).toArray(); } void searchBST(TreeNode curr, Map<Integer, Integer> map) { if (curr == null) return; map.put(curr.val, map.getOrDefault(curr.val, 0) + 1); searchBST(curr.left, map); searchBST(curr.right, map); }
参考搜索搜索树的特性来做题:
ArrayList<Integer> resList; int maxCount; int count; TreeNode pre; public int[] findMode(TreeNode root) { resList = new ArrayList<>(); maxCount = 0; count = 0; pre = null; findMode1(root); int[] res = new int[resList.size()]; for (int i = 0; i < resList.size(); i++) { res[i] = resList.get(i); } return res; } public void findMode1(TreeNode root) { if (root == null) { return; } findMode1(root.left); int rootValue = root.val; // 计数 if (pre == null || rootValue != pre.val) { count = 1; } else { count++; } // 更新结果以及maxCount if (count > maxCount) { resList.clear(); resList.add(rootValue); maxCount = count; } else if (count == maxCount) { resList.add(rootValue); } pre = root; findMode1(root.right); }
236. 二叉树的最近公共祖先
本题其实是比较难的,可以先看我的视频讲解
视频讲解:
自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先_哔哩哔哩_bilibili
题目:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if (root == null || 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) { // 若未找到节点 p 或 q return null; }else if(left == null && right != null) { // 若找到一个节点 return right; }else if(left != null && right == null) { // 若找到一个节点 return left; }else { // 若找到两个节点 return root; } }