題目說明
給你一個二叉樹,請你返回其按 層序遍歷 得到的節點值。 (即逐層地,從左到右訪問所有節點)。
示例:
二叉樹:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其層次遍歷結果:
[
[3],
[9,20],
[15,7]
]
說明
該題對於我來說一共有兩種思路,四種方案。
解題思路一 (層序+深度)
- 該題如果去掉分組,就是一個層序遍歷的問題。加上分組也不過是多深度遍歷一遍
代碼實現一 (1)
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (!root) {
return []
}
let res = [];
function deepNode(root, node) {
node.deep = root.deep + 1;
node.left && deepNode(node, node.left);
node.right && deepNode(node, node.right);
}
deepNode({deep: -1}, root);
let help = [root]
while(help.length) {
let node = help.shift();
node.right && help.unshift(node.right);
node.left && help.unshift(node.left);
if (!res[node.deep]) {
res[node.deep] = [];
}
res[node.deep].push(node.val);
}
return res;
};
代碼實現一 (2)
可以看到實現方式二去掉了while遍歷,使用了一組數組。因爲數組的順序是前序
遍歷的結果,所以標記過每個節點的層級之後,我們其實按順序將它分別放到二維數組中就可以了。
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (!root) {
return []
}
let res = [];
let nodeList = [];
function deepNode(root, node, nodeList) {
node.deep = root.deep + 1;
nodeList.push({
val: node.val,
deep: node.deep
})
node.left && deepNode(node, node.left, nodeList);
node.right && deepNode(node, node.right, nodeList);
}
deepNode({deep: -1}, root, nodeList);
for (let i = 0; i < nodeList.length; i++) {
if (!res[nodeList[i].deep]) {
res[nodeList[i].deep] = [];
}
res[nodeList[i].deep].push(nodeList[i].val);
}
return res;
};
解題思路二 (遞歸 + 動態規劃)
- 首先我們可以這麼想:根節點屬於數組的第一層。
- 那麼第二層該如何得到呢,其實就是按順序遍歷第一層所有節點的左右節點。
- 第三層就是遍歷第二層的所有左右節點。
- 按照這樣理解,這個題就更加清晰了。
- 狀態轉移的方式是將
當前層
的所有子節點
放入下一層
。
代碼實現二 (1)
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (!root) {
return []
}
let nodeList = [[root]];
let res = [[root.val]];
function deepNode(nodeList, row, res) {
nodeList[row + 1] = [];
res[row + 1] = [];
for (let i = 0; i < nodeList[row].length; i++) {
nodeList[row][i].left && (nodeList[row + 1].push(nodeList[row][i].left), res[row+1].push(nodeList[row][i].left.val));
nodeList[row][i].right && (nodeList[row + 1].push(nodeList[row][i].right), res[row+1].push(nodeList[row][i].right.val));
}
if (nodeList[row + 1].length) {
deepNode(nodeList, row + 1, res)
}
}
deepNode(nodeList, 0, res);
res.length -= 1;
return res;
};
代碼實現二 (2)
去掉了遞歸,使用了for循環。
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (!root) {
return []
}
let nodeList = [[root]];
let res = [[root.val]];
for (let i = 0; ; i++) {
nodeList[i + 1] = [];
res[i + 1] = [];
for (let j = 0; j < nodeList[i].length; j++) {
nodeList[i][j].left && (nodeList[i + 1].push(nodeList[i][j].left), res[i + 1].push(nodeList[i][j].left.val));
nodeList[i][j].right && (nodeList[i + 1].push(nodeList[i][j].right), res[i + 1].push(nodeList[i][j].right.val));
}
if (!nodeList[i + 1].length) {
break;
}
}
res.length -= 1;
return res;
};