530.二叉搜索树的最小绝对差
思路:
题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。
注意是二叉搜索树,二叉搜索树可是有序的。
遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。
代码实现:
//递归 先转换为有序数组
var getMinimumDifference = function (root) {
let arr = [];
const bulidArr = (root) => {
if (root) {
bulidArr(root.left)
arr.push(root.val);
bulidArr(root.right)
}
}
bulidArr(root)
//因为是一个有序数组 初始定义一个最大值进行比较
let diff = arr[arr.length - 1];
for (let i = 0; i < arr.length; i++) {
if (diff > arr[i] - arr[i - 1]) {
diff = arr[i] - arr[i - 1]
}
}
return diff
}
//递归 在递归的过程中更新最小值
var getMinimumDifference = function (root) {
let res = Infinity
let preNode = null;
//中序遍历
const inorder = (root) => {
if (!root) {
return
}
inorder(root.left);
if (preNode) {
res = Math.min(res, root.val - preNode.val)//3 3
}
console.log(preNode)
preNode = root// 1 4 7
inorder(root.right)
}
inorder(root)
return res
}
//迭代 中序遍历
var getMinimumDifference = function (root) {
let stack = [];
let pre = null;
let cur = root;
let res = Infinity;
while (cur || stack.length) {
if (cur) {
stack.push(cur);
cur = cur.left
} else {
cur = stack.pop();
if (pre) {
res = Math.min(res, cur.val - pre.val)
}
pre = cur
cur = cur.right
}
}
return res
}
501.二叉搜索树中的众数
代码实现:
// 使用额外空间map的方法
var findMode = function (root) {
let map = new Map()
const searchBst = (root) => {
if (!root) return;
searchBst(root.left);
map.set(root.val, map.has(root.val) ? map.get(root.val) + 1 : 1);
searchBst(root.right)
}
searchBst(root)
//上面把数据都存储到map
//下面开始寻找map里面的
// 定义一个最大出现次数的初始值为root.val的出现次数
let maxCount = map.get(root.val);
let res = [];
for (let [key, value] of map) {
if (value === maxCount) {
res.push(key)
} else if (value > maxCount) {
// 如果value的值大于原本的maxCount就清空res的所有值,因为找到了更大的
res = [];
maxCount = value;
res.push(key)
}
}
return res
};
// 不使用额外空间,利用二叉树性质,中序遍历(有序):
var findMode = function (root) {
let count = 0, maxCount = 1;
let pre = root, res = [];
const travelTree = function (cur) {
if (cur === null) {
return;
}
travelTree(cur.left);
if (pre.val === cur.val) {
count++
} else {
count = 1
}
pre = cur
if (count === maxCount) {
res.push(cur.val)
}
if (count > maxCount) {
res = [];
maxCount = count
res.push(cur.val)
}
travelTree(cur.right)
}
travelTree(root);
return res
};
//迭代
var findMode = function (root) {
let count = 0, maxCount = 0;
let cur = root, pre = null, stack = [];
let result = [];
while (cur || stack.length) {
if (cur) {
stack.push(cur)
cur = cur.left
} else {
cur = stack[stack.length - 1]
stack.pop()
if (pre === null) {
count = 1
} else if (pre.val === cur.val) {
count++
} else {
count = 1
}
if (count === maxCount) {
result.push(cur.val)
} else if (count > maxCount) {
maxCount = count
result = []
result.push(cur.val)
}
pre = cur;
cur = cur.right
}
return result
}
};
236. 二叉树的最近公共祖先
思路:
遇到这个题目首先想的是要是能自底向上查找就好了,这样就可以找到公共祖先了。
那么二叉树如何可以自底向上查找呢?
回溯啊,二叉树回溯的过程就是从低到上。
后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑。
代码实现
var lowestCommonAncestor = function (root, p, q) {
const travelTree = (root, p, q) => {
if (root === q || root === p || root === null) return root
let left = travelTree(root.left, p, q)
let right = travelTree(root.right, p, q)
if (left !== null && right !== null) {
return root
}
if (left === null) {
return right
}
return left;
}
return travelTree(root, p, q);
};
总结
关于双指针回溯的问题这里需要多加注意