[H二叉树] lc987. 二叉树的垂序遍历(dfs+哈希表)

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[H二叉树] lc987. 二叉树的垂序遍历(dfs+哈希表)相关的知识,希望对你有一定的参考价值。

1. 题目来源

链接:987. 二叉树的垂序遍历

2. 题目解析

名不副实的困难题。

dfs 遍历时记录每个节点的列号,将同列的元素统一存放即可。 列号就是根节点为 0,若向左孩子走则 -1,右孩子走则加 1。

但是涉及到一个问题,要求同列元素,先按行号高低排序,同行的再按大小排序。这就比较恶心了,一开始没看到 WA 了一发,样例做了详细图解。

那就在记录列号的基础上,在记录行号,map<int, vector<vector<int>> 即为 <列号, <行号,元素值>> 在这是利用二维数组的排序特性,第一个元素是行号,第二个元素是元素值。那么会先按第一个元素排,即按照行号从小到大排,同行的,会按照第二元素排,即按照元素的从小到大再排,和 pair 规则相同。二维数组可以直接排序,就是按照关键字顺序来排的。

这样就将 (x,y) 与元素值一一对应起来了。


  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度 O ( n ) O(n) O(n)

代码:

二维数组中的第一个元素没用啊,存行号,方便排序罢了。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    map<int, vector<vector<int>>> m;
    void dfs(TreeNode* root, int x, int y) {
        if (!root) return ;
        m[y].push_back({x, root->val});
        dfs(root->left, x + 1, y - 1);
        dfs(root->right, x + 1, y + 1);
    }
    vector<vector<int>> verticalTraversal(TreeNode* root) {
        dfs(root, 0, 0);

        vector<vector<int>> res;
        for (auto& [k, v] : m) {
            sort(v.begin(), v.end());
            vector<int> t;
            for (auto e : v) t.push_back(e[1]);
            res.push_back(t);
        }

        return res;
    }
};

以上是关于[H二叉树] lc987. 二叉树的垂序遍历(dfs+哈希表)的主要内容,如果未能解决你的问题,请参考以下文章

987. 二叉树的垂序遍历

递归987. 二叉树的垂序遍历(困难)

987. 二叉树的垂序遍历

二叉树的垂序遍历

LeetCode 987. 二叉树的垂序遍历

591,二叉树的垂序遍历