目录
530.二叉搜索树的最小绝对差
给你一个二叉搜索树的根节点
root
,返回 树中任意两不同节点值之间的最小差值 。差值是一个正数,其数值等于两值之差的绝对值。
*掌握二叉树上的双指针操作
class Solution {
/**
* 二叉搜索树上的最小的差值,二叉搜索树的中序遍历数组是一个递增数组
*
* @param root
* @return
*/
List<Integer> list = new ArrayList<>();
public int getMinimumDifference(TreeNode root) {
circle(root);
int min = Integer.MAX_VALUE;
for (int i = 1; i < list.size(); i++) {
int temp = list.get(i) - list.get(i - 1);
min = temp < min ? temp : min;
}
return min;
}
public void circle(TreeNode root) {
if (root == null) {
return;
}
circle(root.left);
list.add(root.val);
circle(root.right);
}
}
双指针方法,利用一个指针pre在递归中记录上一个指针,point:pre初始化为null
class Solution {
/**
* 二叉搜索树上的最小的差值,二叉搜索树的中序遍历数组是一个递增数组
*
* @param root
* @return
*/
int min = Integer.MAX_VALUE;
TreeNode pre = null ;//记录中序遍历的上一个
public int getMinimumDifference(TreeNode root) {
if (root == null) {
return 0;
}
circle(root);
return min;
}
public void circle(TreeNode root) {
if (root == null) {
return;
}
circle(root.left);
if (pre != null) {
min = Math.min(min, root.val - pre.val);
}
pre = root;
circle(root.right);
}
}
501.二叉搜索树中的众数
在普通树上进行搜索,将中序遍历数组放在map里面统计数和个数
class Solution {
/**
* 返回二叉搜索树中的众数,二叉搜索树中序遍历数组是一个单调递增的数组
*
* @param root
* @return
*/
List<Integer> nu = new ArrayList<>();
public int[] findMode(TreeNode root) {
dou(root);
int[] nums = nu.stream().mapToInt(Integer::intValue).toArray();
List<Integer> ans = new ArrayList<>();
HashMap<Integer, Integer> hashMap = new HashMap<>();//把数组放进hashmap里面<值,次数>
for (int i = 0; i < nums.length; i++) {
if (hashMap.containsKey(nums[i])) {
int temp = hashMap.get(nums[i]) + 1;
hashMap.put(nums[i], temp);
} else {
hashMap.put(nums[i], 1);
}
}
//遍历一遍hashmap的value找到最大的数
int max = Integer.MIN_VALUE;
for (Map.Entry<Integer, Integer> entry : hashMap.entrySet()) {
max = max > entry.getValue() ? max : entry.getValue();
}
for (Map.Entry<Integer, Integer> entry : hashMap.entrySet()) {
if (entry.getValue().equals(max)) {
ans.add(entry.getKey());
}
}
return ans.stream().mapToInt(Integer::intValue).toArray();
}
public void dou(TreeNode root) {
if (root == null) {
return;
}
dou(root.left);
nu.add(root.val);
dou(root.right);
}
}
而在有序数组中,我一开始担心的就是虽然用cnt记录了当前数出现的次数,但是我如何才能知道,什么时候cnt是最大值,我要把这个数放进结果集里面?
可以利用一个maxvalue,maxvalue实时更新,当然更新完之后要把之前是maxvalue放进结果集里的结果集进行清空操作。
class Solution {
/**
* 返回二叉搜索树中的众数,二叉搜索树中序遍历数组是一个单调递增的数组
*
* @param root
* @return
*/
List<Integer> ans = new ArrayList<>();
TreeNode pre = null;
int cnt = 0;
int max = Integer.MIN_VALUE;
public int[] findMode(TreeNode root) {
dou(root);
return ans.stream().mapToInt(Integer::intValue).toArray();
}
public void dou(TreeNode root) {
if (root == null) {
return;
}
dou(root.left);
if (pre == null) {
cnt = 1;
} else {
if (root.val == pre.val) {//下一个跟上一个值一样,计数器+1
cnt++;
} else {
cnt = 1;
}
}
if (cnt == max) {
ans.add(root.val);
}
if (max < cnt) {
max = cnt;
ans.clear();
ans.add(root.val);
}
pre = root;
dou(root.right);
}
}
分为两步骤,一部分计算当前的cnt就是当前这个数出现的次数。第二部分,对cnt处理。
*236.二叉树的最近公共祖先
二叉树的最近公共祖先,需要回溯遍历整个树,然后把结果返回给头结点
class Solution {
/**
* 二叉树的公共祖先
*
* @param root
* @param p
* @param q
* @return
*/
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return dou(root, p, q);
}
public TreeNode dou(TreeNode root, TreeNode p, TreeNode q) {
//递归的出口
if (root == null) {
return null;
}
if (root == p || root == q) {
return root;
}
//单层递归的逻辑----->后序遍历+回溯
TreeNode left = dou(root.left, p, q);
TreeNode right = dou(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;
}
return null;
}
}
2022.11.27补