538\. 把二叉搜索树转换为累加树
# 538. 把二叉搜索树转换为累加树 (opens new window)
# Description
Difficulty: 中等
Related Topics: 树 (opens new window), 深度优先搜索 (opens new window), 二叉搜索树 (opens new window), 二叉树 (opens new window)
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node
的新值等于原树中大于或等于 node.val
的值之和。
提醒一下,二叉搜索树满足下列约束条件:
- 节点的左子树仅包含键 小于 节点键的节点。
- 节点的右子树仅包含键 大于 节点键的节点。
- 左右子树也必须是二叉搜索树。
**注意:**本题和 1038: 相同
示例 1:
输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
1
2
2
示例 2:
输入:root = [0,null,1]
输出:[1,null,1]
1
2
2
示例 3:
输入:root = [1,0,2]
输出:[3,3,2]
1
2
2
示例 4:
输入:root = [3,2,4,1]
输出:[7,9,4,10]
1
2
2
提示:
- 树中的节点数介于
0
和 104之间。 - 每个节点的值介于 -104 和 104 之间。
- 树中的所有值 互不相同 。
- 给定的树为二叉搜索树。
# Solution
Language: JavaScript
# 先序遍历(PreOrder, 按照先访问根节点的顺序)
var preorderTraversal = function(root) {
const res = []
function traversal (root) {
if (root !== null) {
res.push(root.val) // 访问根节点的值
traversal(root.left) // 递归遍历左子树
traversal(root.right) // 递归遍历右子树
}
}
traversal(root)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 94 中序遍历(InOrder, 按照根节点在中间访问的顺序)
var inorderTraversal = function(root) {
const res = []
function traversal(root) {
if (root !== null) {
traversal(root.left)
res.push(root.val)
traversal(root.right)
}
}
traversal(root)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 145 后续遍历(PosterOrder, 按照根节点在后面访问的顺序)
var postorderTraversal = function(root) {
const res = []
function traversal(root) {
if (root !== null) {
traversal(root.left)
traversal(root.right)
res.push(root.val)
}
}
traversal(root)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 100 相同的树
可以利用这种递归思想并发同时爬两棵树
var isSameTree = function(p, q) {
function traversal (root1, root2) {
if (root1 === null && root2 !== null) {
return false
} else if (root1 !== null && root2 === null) {
return false
} else if (root1 === null && root2 === null) {
return true
} else {
return root1.val === root2.val && traversal(root1.left, root2.left) && traversal(root1.right, root2.right)
}
}
return traversal(p, q)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 226 翻转二叉树
var invertTree = function(root) {
function traversal (root) {
if (root === null) {
return null
} else {
[root.left, root.right] = [traversal(root.right), traversal(root.left)]
return root
}
}
return traversal(root)
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 590 N叉树的后序遍历
var postorder = function(root) {
const res = []
function traversal (root) {
if (root !== null) {
root.children.forEach(child => {
traversal(child)
})
res.push(root.val)
}
}
traversal(root)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
var postorder = function(root) {
const res = []
;(function (root) {
if (root !== null) {
root.children.forEach(child => {
arguments.callee(child)
})
res.push(root.val)
}
})(root)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
var postorder = function(root) {
if (root === null) {
return []
}
const res = []
const arr = [root]
while (arr.length) {
const cur = arr.pop()
res.push(cur.val)
for (let i = cur.children.length - 1; i >= 0; i--) {
arr.push(cur.children[i])
}
}
return res.reverse()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 103 二叉树的锯齿形层次遍历
var zigzagLevelOrder = function(root) {
if (root === null) {
return []
} else {
let res = []
function traversal (root, depth) {
if (root !== null) {
if (res[depth] === undefined) {
res[depth] = []
}
res[depth].push(root.val)
traversal(root.left, depth + 1)
traversal(root.right, depth + 1)
}
}
traversal(root, 0)
res.forEach((item, index) => {
if (index & 1) {
res[index] = item.reverse()
}
})
return res
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 优化
var zigzagLevelOrder = function(root) {
if (root === null) {
return []
} else {
let res = []
function traversal (root, depth) {
if (root !== null) {
if (res[depth] === undefined) {
res[depth] = []
}
if (depth & 1) {
res[depth].unshift(root.val)
} else {
res[depth].push(root.val)
}
traversal(root.left, depth + 1)
traversal(root.right, depth + 1)
}
}
traversal(root, 0)
return res
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 230 二叉搜索树中第K小的元素
var kthSmallest = function (root, k) {
let arr = []
function traversal (node) {
if (node !== null) {
traversal(node.left)
arr.push(node.val)
traversal(node.right)
}
}
traversal(root)
return arr[k - 1]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
// 优化
var kthSmallest = function (root, k) {
let arr = []
function traversal(node) {
if (node !== null && arr.length < k) {
traversal(node.left)
arr.push(node.val)
traversal(node.right)
}
}
traversal(root)
return arr[k - 1]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
// 优化
var kthSmallest = function (root, k) {
let res
let count = 0
function traversal(node) {
if (node !== null) {
if (count < k) {
traversal(node.left)
}
if (++count === k) {
res = node.val
}
if (count < k) {
traversal(node.right)
}
}
}
traversal(root)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 102 二叉树的层序遍历
var levelOrder = function(root) {
const res = []
function traversal (root, depth) {
if (root !== null) {
if (!res[depth]) {
res[depth] = []
}
traversal(root.left, depth + 1)
res[depth].push(root.val)
traversal(root.right, depth + 1)
}
}
traversal(root, 0)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 199 二叉树的右视图
基本思路: 先序遍历, 记录每一层深度下的节点的值, 并先记录左节点再记录右节点, 则最后记录的值即为该层深度的右视图看到的值
var rightSideView = function(root) {
const arr = []
function traversal (root, depth) {
if (root) {
if (arr[depth] === undefined) {
arr[depth] = []
}
arr[depth].push(root.val)
traversal(root.left, depth + 1)
traversal(root.right, depth + 1)
}
}
traversal(root, 0)
const res = []
for (let i = 0; i < arr.length; ++i) {
res.push(arr[i][arr[i].length - 1])
}
return res
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 104 二叉树的最大深度
var maxDepth = function (root) {
let res = 0
function traversal (root, depth) {
if (root !== null) {
if (depth > res) {
res = depth
}
if (root.left) {
traversal(root.left, depth + 1)
}
if (root.right) {
traversal(root.right, depth + 1)
}
}
}
traversal(root, 1)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 107 二叉树的层次遍历 II
var levelOrderBottom = function(root) {
if (root === null) {
return []
}
let res = []
function traversal (root, depth) {
if (root !== null) {
if (!res[depth]) {
res[depth] = []
}
traversal(root.left, depth + 1)
res[depth].push(root.val)
traversal(root.right, depth + 1)
}
}
traversal(root, 0)
return res.reverse()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 671 二叉树中第二小的节点
var findSecondMinimumValue = function(root) {
let arr = []
;(function traversal (root) {
if (root !== null) {
traversal(root.left)
arr.push(root.val)
traversal(root.right)
}
})(root)
let _arr = [...new Set(arr)].sort()
return _arr[1] ? _arr[1] : -1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 1038 从二叉搜索树到更大和树
var bstToGst = function(root) {
let sum = 0
function traversal (root) {
if (root !== null) {
traversal(root.right)
root.val += sum
sum = root.val
traversal(root.left)
}
}
traversal(root)
return root
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 700 二叉搜索树中的搜索
var searchBST = function(root, val) {
function traversal (root) {
if (root !== null) {
if (root.val === val) {
return root
} else if (root.val < val) {
return traversal(root.right)
} else {
return traversal(root.left)
}
} else {
return root
}
}
return traversal(root)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 559 N叉树的最大深度
var maxDepth = function(root) {
if (root === null) {
return 0
} else {
let depth = 1
function traversal (root, curDepth) {
if (root !== null) {
if (curDepth > depth) {
depth = curDepth
}
root.children.forEach(child => traversal(child, curDepth + 1))
}
}
traversal(root, 1)
return depth
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 589 N叉树的前序遍历
var preorder = function(root) {
const res = []
function traversal (root) {
if (root !== null) {
res.push(root.val)
root.children.forEach(child => traversal(child))
}
}
traversal(root)
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 897 递增顺序查找树
var increasingBST = function(root) {
const arr = []
function traversal (root) {
if (root !== null) {
traversal(root.left)
arr.push(root.val)
traversal(root.right)
}
}
traversal(root)
const res = new TreeNode(arr[0])
let currentNode = res
for (let i = 0; i < arr.length - 1; i++) {
currentNode.left = null
currentNode.right = new TreeNode(arr[i + 1])
currentNode = currentNode.right
}
return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 538 把二叉搜索树转换为累加树
/**
* 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 {TreeNode}
*/
var convertBST = function(root) {
let sum = 0
function traversal (root) {
if (root !== null) {
traversal(root.right)
sum += root.val
root.val = sum
traversal(root.left)
}
}
traversal(root)
return root
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26