987. 二叉树的垂序遍历

987. 二叉树的垂序遍历

 


题目

传送门:https://leetcode.cn/problems/vertical-order-traversal-of-a-binary-tree/


 


算法设计:深度优先搜索

因为返回顺序是,按列的。

所以,需要先给每个节点标上坐标。

void traverse(TreeNode root, int row = 0, int col = 0) {  // 给每个节点标记坐标
    if (root == null) 
        return;
    print(row, col);
    traverse(root.left, row + 1, col - 1);
    traverse(root.right, row + 1, col + 1);
}

把这些坐标收集起来,依据题目要求进行排序,再组装成题目要求的返回数据格式。

  • 整体顺序:从最左列开始,到最右列结束 -> 首先根据 y 值从小到大排序
  • 列顺序:多节点同列,从上到下的升序 -> 其次根据 x 值从小到大排序
  • 局部顺序:同行同列有多节点,按节点值从小到大升序 -> 最后根据 val 值从小到大排序
struct Node {
    int x, y, val;
    Node() {}
    Node(int a, int b, int c) : x(a), y(b), val(c) {}
    bool operator < (Node node) const {             // 重载 < 排序
        if(y != node.y) return y > node.y;          // 首先根据 y 值从小到大排序
        else if(x != node.x) return x > node.x;     // 其次根据 x 值从小到大排序
        return val > node.val;                      // 最后根据 val 值从小到大排序
    }
};

完整代码:

class Solution {
public:
    struct Node {
        int x, y, val;
        Node() {}
        Node(int a, int b, int c) : x(a), y(b), val(c) {}
        bool operator < (Node node) const {
            if(y != node.y) return y > node.y;
            else if(x != node.x) return x > node.x;
            return val > node.val;
        }
    };

    map <int, priority_queue <Node> > ss;         // 优先队列排序
    vector <vector<int>> ans;

    void dfs(int x, int y, TreeNode *root) {
        if(!root) return ;
        ss[y].push({x, y, root->val});
        dfs(x + 1, y - 1, root->left);
        dfs(x + 1, y + 1, root->right);
        return ;
    }

    vector<vector<int>> verticalTraversal(TreeNode* root) {
        if(!root) return ans;
        dfs(0, 0, root);
        for(auto &[x, y] : ss) {
            ans.push_back(vector<int>());
            while(!y.empty()) {
                ans.back().push_back(y.top().val);
                y.pop();
            }
        }
        return ans;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值