654.最大二叉树
构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
代码实现:
function TreeNode (val, left, right) {
this.val = (val === undefined ? 0 : val)
this.left = (left === undefined ? null : left)
this.right = (right === undefined ? null : right)
}
var constructMaximumBinaryTree = function (nums) {
const setTree = (nums, left, right) => {
if (left > right) {
return null
}
let index = -1, maxNums = -1;
for (let i = left; i <= right; ++i) {
if (nums[i] > maxNums) {
maxNums = nums[i]
index = i
}
}
let node = new TreeNode(maxNums)//中
node.left = setTree(nums, left, index - 1)
node.right = setTree(nums, index + 1, right)
return node
}
let root = setTree(nums, 0, nums.length - 1)
return root
};
617.合并二叉树
其实和遍历一个树逻辑是一样的,只不过传入两个树的节点,同时操作
代码实现:
function TreeNode (val, left, right) {
this.val = (val === undefined ? 0 : val)
this.left = (left === undefined ? null : left)
this.right = (right === undefined ? null : right)
}
var mergeTrees = function (root1, root2) {
const setTree = (root1, root2) => {
if (root1 === null) {
return root2
}
if (root2 === null) {
return root1
}
root1.val += root2.val
root1.left = setTree(root1.left, root2.left)
root1.right = setTree(root1.right, root2.right)
return root1
}
return setTree(root1, root2)
};
//生成新的二叉树
var mergeTrees = function (root1, root2) {
const setTree = (root1, root2) => {
if (root1 === null) {
return root2
}
if (root2 === null) {
return root1
}
let newRoot = new TreeNode(0)
newRoot.val = root1.val + root2.val
newRoot.left = setTree(root1.left, root2.left)
newRoot.right = setTree(root1.right, root2.right)
return newRoot
}
return setTree(root1, root2)
};
//迭代法
var mergeTrees = function (root1, root2) {
if (root1 === null) {
return root2
}
if (root2 === null) {
return root1
}
let queue = []
queue.push(root1)
queue.push(root2)
while (queue.length) {
let node1 = queue.shift()
let node2 = queue.shift()
node1.val += node2.val
if (node1.left !== null && node2.left !== null) {
queue.push(node1.left)
queue.push(node2.left)
}
if (node1.right !== null && node2.right !== null) {
queue.push(node1.right)
queue.push(node2.right)
}
if (node1.left == null && node2.left !== null) {
node1.left = node2.left
}
if (node1.right == null && node2.right !== null) {
node1.right = node2.right
}
}
return root1
};
700.二叉搜索树中的搜索
二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样。
代码实现
function TreeNode (val, left, right) {
this.val = (val === undefined ? 0 : val)
this.left = (left === undefined ? null : left)
this.right = (right === undefined ? null : right)
}
var searchBST = function (root, val) {
if (root === null || root.val === val) {
return root
}
let result = null;
if (val < root.val) {
result = searchBST(root.left, val)
}
if (val > root.val) {
result = searchBST(root.right, val)
}
return result
};
//迭代
var searchBST = function (root, val) {
while (root) {
if (val < root.val) {
root = root.left
} else if (val > root.val) {
root = root.right
} else {
return root
}
}
return null
};
98.验证二叉搜索树
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
代码实现
//辅助数组解决
var isValidBST = function (root) {
let arr = []
const traversal = (root) => {
if (root === null) return;
traversal(root.left)
arr.push(root.val)
traversal(root.right)
}
traversal(root)
for (let i = 0; i < arr.length; i++) {
if (arr[i] <= arr[i - 1]) return false
}
return true
};
//递归中解决
var isValidBST = function (root) {
let pre = null
const inorder = (root) => {
if (root === null) return true;
let left = inorder(root.left);
if (pre !== null && pre.val >= root.val) {
return false
}
pre = root
let right = inorder(root.right)
return left && right
}
return inorder(root)
};
总结
总体来说不是很难理解 但是有很多坑容易踩中 包括理解递归的终止条件等等也十分重要 加油!!