代码随想录的第十八天(二叉树)
530. 二叉搜索树的最小绝对差
var getMinimumDifference = function(root) {
let arr = []
function getMin (root) {
if (root === null) return
if (root.left) getMin(root.left)
arr.push(root.val)
if (root.right) getMin(root.right)
}
getMin(root)
let diff = arr[arr.length - 1];
for (let i = 1; i < arr.length; i++) {
if (diff > arr[i] - arr[i - 1]) {
diff = arr[i] - arr[i - 1]
}
}
return diff;
};
递归辅助数组的思路:
1、因为是二叉搜索树,所以当中序遍历的时候存储的值就是递增的
2、只需要判断相邻两个数之间的差值就能得出
var getMinimumDifference = function(root) {
let res = Infinity
let pre = null
function getMin (root) {
if (root === null) return
getMin(root.left)
if (pre) res = Math.min(res, root.val - pre.val)
pre = root
getMin(root.right)
}
getMin(root)
return res
};
递归直接求思路:
1、也是根据中序遍历是递增,首先先存储下当前的root的值,然后下次进来用当前的val减去上次的val(和辅助数组思路类似),求出最小值
501. 二叉搜索树中的众数
var findMode = function(root) {
const map = new Map()
function getArr(root) {
if (!root) return
if (map.has(root.val)) {
map.set(root.val, map.get(root.val) + 1)
} else {
map.set(root.val, 1)
}
if (root.left) getArr(root.left)
if (root.right) getArr(root.right)
}
getArr(root)
const mapNew = [...map.entries()].sort((a,b) => b[1] - a[1])
const res = []
for (let i = 0; i < mapNew.length; i++) {
if (mapNew[i][1] === mapNew[0][1]) {
res.push(mapNew[i][0])
}
}
return res
};
辅助哈希表思路:不多赘述,可以求解普通二叉树
var findMode = function(root) {
let res = [], pre = root,count = 0, maxCount = 1
function getTravel (root) {
if (!root) return
getTravel(root.left)
if (pre.val === root.val) {
count++
} else {
count = 1
}
pre = root
if (count === maxCount) {
res.push(root.val)
}
if (count > maxCount) {
res = []
maxCount = count
res.push(root.val)
}
getTravel(root.right)
}
getTravel(root)
return res
};
双指针递归思路:
1、需要记录当前的最大数次数,和一个动态的次数值
2、因为是二叉搜索树,所以中序遍历就是递增的,相邻的值相同时就将动态次数值加一,否则就就记为新的一次
3、如果是和最大出现次数相同就将值存储
4、如果动态次数大于之前的最大次数,说明有新的众数出现,进行清空数组赋值,同时更新出现的最大的次数
236. 二叉树的最近公共祖先
var lowestCommonAncestor = function(root, p, q) {
if (root === null || root === p || root === q) {
return root
}
let left = lowestCommonAncestor(root.left, p, q)
let right = lowestCommonAncestor(root.right, p, q)
if (left !== null && right !== null) {
return root
}
if (left === null) {
return right
}
return left
};
思路:
1、后序遍历,返回中间的值就是最终的最近公共祖先
2、首先判断,如果遍历到子节点或者等于目标值就将当前值进行返回
3、遍历左右子树,当左右子树都不为空的时候,那么当前的这个节点就是最近的公共祖先
4、如果左子树为空,那么就返回右子树,在接着往下走,否则就返回左子树