leetcode 987题

Posted by franki on November 19, 2020

leetcode 987题 二叉树的垂序遍历

给定二叉树,按垂序遍历返回其结点值。

对位于 (X, Y) 的每个结点而言,其左右子结点分别位于 (X-1, Y-1) 和 (X+1, Y-1)。

把一条垂线从 X = -infinity 移动到 X = +infinity ,每当该垂线与结点接触时,我们按从上到下的顺序报告结点的值( Y 坐标递减)。

如果两个结点位置相同,则首先报告的结点值较小。

按 X 坐标顺序返回非空报告的列表。每个报告都有一个结点值列表。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

示例 1

输入:[3,9,20,null,null,15,7]
输出:[[9],[3,15],[20],[7]]
解释:
在不丧失其普遍性的情况下,我们可以假设根结点位于 (0, 0):
然后,值为 9 的结点出现在 (-1, -1);
值为 3 和 15 的两个结点分别出现在 (0, 0)(0, -2);
值为 20 的结点出现在 (1, -1);
值为 7 的结点出现在 (2, -2)。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

1 利用 bfs ,遍历所有的节点,把所有的节点记录在一个对象中,这个对象保存了所在节点的val,坐标x,坐标y信息

2 对于对象的 key 进行排序,得到 key 排序数组

3 key 排序数组依次遍历,得到最终的结果

注意:

需要遵守以下规则:

  • 坐标 x 值越小,排在前面
  • x 值相等,y 值越大,排在前面
  • x 值, y 值都相等,比较两者的 val,val 值小的排在前面

代码

function verticalTraversal(root) {
    if (root === null) return null;
    // bfs
    const arr = [{node: root, x: 0, y: 0}];
    const obj = {};
    while (arr.length) {
        const curr = arr.shift();
        const {node, x, y} = curr;
        const {left, right} = node;
        if (obj[x] === undefined) {
            obj[x] = [{val: node.val, y}];
        } else {
            obj[x].push({val: node.val, y});
        }
        if (left) {
            arr.push({node: left, x: x - 1, y: y - 1});
        }
        if (right) {
            arr.push({node: right, x: x + 1, y: y - 1});
        }
    }

    // sort
    const keysArr = Object.keys(obj).sort((a, b) => a - b);

    // compose res
    const res = [];

    keysArr.forEach(key => {
        // sort
        obj[key].sort((a, b) => {
            // 当两者y相等,val值小的排在前面
            if (a.y === b.y) {
                return a.val - b.val;
            }
            // y值大的排在前面
            return b.y - a.y;
        });

        // 拼凑结果
        const tempArr = [];
        obj[key].forEach(item => {
            tempArr.push(item.val);
        });

        res.push(tempArr);
    });

    return res;
}

复杂度分析

  • 时间复杂度: O(n)
  • 空间复杂度: O(n)