530 二叉搜索树的最小绝对差
题目链接/文章讲解:https://programmercarl.com/0530.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%BB%9D%E5%AF%B9%E5%B7%AE.html
视频讲解:https://www.bilibili.com/video/BV1DD4y11779
方法一:自己写的,先变成有序数组再处理
一开始以为直接把中序数组的第二个数字减第一个数字就可以了,但试了一下发现可能差值更小的在后面,后来画图发现都是两个两个这么计算,就想到了双指针滑动窗口
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var getMinimumDifference = function(root) {
let arr = [];
const inorder = (root) => {
if(root === null) return null;
inorder(root.left);
arr.push(root.val);
inorder(root.right);
}
inorder(root);
let res = [];
let i = 0,j = i+1;
while(i<j && j<arr.length){
res.push(arr[j]-arr[i]);
i++;
j++;
}
return Math.min(...res);
};
但是下面这种写法更好一点,只是新建了一个变量,我的方法是新建了一个数组。
方法二:在递归的过程中更新最小值
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var getMinimumDifference = function(root) {
let res = Infinity;
let pre = null;
const inorder = (root) => {
if(root === null) return null;
inorder(root.left);
if(pre) res = Math.min(res,root.val-pre.val);
pre = root;
inorder(root.right);
}
inorder(root);
return res;
};
501 二叉搜索树中的众数
https://programmercarl.com/0501.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E4%BC%97%E6%95%B0.html
视频讲解:https://www.bilibili.com/video/BV1fD4y117gp
方法一:自己写的(适用于求二叉树的众数)
自己想的思路,但是没有用上二叉搜索树的特性,而且感觉很麻烦,有很多小细节要注意
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var findMode = function(root) {
if(root === null) return null;
let arr = [];
const inorder = (root) => {
if(root === null) return null;
inorder(root.left);
arr.push(root.val);
inorder(root.right);
}
inorder(root);
const map = new Map();
for(let i = 0;i<arr.length;i++){
if(map.has(arr[i])){
map.set(arr[i],map.get(arr[i])+1);
}else{
map.set(arr[i],1);
}
}
let maxKey = [];
let maxValue = -Infinity;
for(const [key,value] of map){
if(value > maxValue){
maxValue = value;
maxKey = [key];
}else if(value === maxValue){ //如果相等这种情况也要列举出来
maxKey.push(key);
}
}
return maxKey;
};
方法二:笨猪爆破组
思路
访问每一个节点时,我们希望重复的节点值相邻被访问,便于:一边统计出现次数,一边看是否出现了最大出现次数。即,希望访问的节点值是有序的,对于 BST 来说,中序遍历能做到。本题的 BST 中序遍历,访问的节点值是非严格递增的。
处理当前的节点值
prev 变量,保存上一个出现的、不同的节点值。
modes 数组,保存出现次数最多的节点值们。
1、访问到一个重复的节点值,频次 freq +1
如果 freq 大于最大频次 maxFreq,更新 maxFreq,并且 modes 数组直接更新为[root.val],不使用原有数组。
如果 freq 等于 maxFreq,则将当前节点值加入 modes 数组。
如果 freq 小于 maxFreq,不造成影响,什么都不做。
2、访问到一个新的不同的节点值,频次 freq 归 1,并且更新 prev。之前的最高频次已经存到 maxFreq,现在要看新的节点值的频次,能否打破纪录。
如果 freq 大于最大纪录,更新 maxFreq,更新 modes 为 [root.val]。
如果 freq 等于 maxFreq,则将当前节点值加入 modes 数组。
如果 freq 小于 maxFreq,不造成影响,什么都不做。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var findMode = function(root) {
let modes = []; //存储众数的数组
let freq = 0; //频次
let maxFreq = 0;
let prev = 0; //存储上一个出现的,不同的节点值
const handle = (rootVal) => {
if(rootVal === prev){ //访问到重复的节点值
freq++;
}else{ //如果是不重复的节点值
freq = 1; //将频次归为1
prev = rootVal; //更新prev
}
//看频次是否能打破之前的maxFreg
if(freq > maxFreq){ //频次大于之前保存的最大频次,即打破纪录
maxFreq = freq; //更新最大频次
modes = [rootVal]; //更新modes数组
}else if(freq === maxFreq){ //如果频次相等
modes.push(rootVal); //则push进去
}
}
const inorder = (root) => {
if(root === null) return null;
inorder(root.left);
handle(root.val); //将处理节点这一步的逻辑抽出来
inorder(root.right);
}
inorder(root);
return modes;
};
236 二叉树的最近公共祖先
https://programmercarl.com/0236.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88.html
视频讲解:https://www.bilibili.com/video/BV1jd4y1B7E2
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function(root, p, q) {
//如果当前节点本身为空,或者当前节点就是p或者q,则直接返回当前节点
if(root === null || root === p || root === q){
return root;
}
const left = lowestCommonAncestor(root.left,p,q);
const right = lowestCommonAncestor(root.right,p,q);
if(left && right){ //一个点在左子树,一个点在右子树,则直接返回当前节点
return root;
}
if(left === null){ //如果左子树为空,即两个点都不在左子树中,则返回右节点
return right;
}
return left; //否则返回左节点
};