987. 二叉树的垂序遍历 力扣(困难) bfs+hash+优先队列 感觉还是简单的,就是复杂了点
987. 二叉树的垂序遍历
给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。
对位于 (row, col) 的每个结点而言,其左右子结点分别位于 (row + 1, col - 1) 和 (row + 1, col + 1) 。树的根结点位于 (0, 0) 。
二叉树的 垂序遍历 从最左边的列开始直到最右边的列结束,按列索引每一列上的所有结点,形成一个按出现位置从上到下排序的有序列表。如果同行同列上有多个结点,则按结点的值从小到大进行排序。
返回二叉树的 垂序遍历 序列。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[9],[3,15],[20],[7]]
解释:
列 -1 :只有结点 9 在此列中。
列 0 :只有结点 3 和 15 在此列中,按从上到下顺序。
列 1 :只有结点 20 在此列中。
列 2 :只有结点 7 在此列中。
学习要点:
priority_queue的遍历,只能通过while(!Q.empty()) 做
pair的用法,可以用make_pair制作,变量类型是 < , >
代码:
/** * 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: struct node{ int val; int row; node(int x,int y){val=x; row=y;} }; struct cmp { bool operator()(node a,node b) { if(a.row!=b.row) return a.row>b.row; else return a.val>b.val; } }; vector<vector<int>> verticalTraversal(TreeNode* root) { queue< pair< TreeNode*,pair<int,int> > > Q; // 指针, 行号,列号 map<int, priority_queue<node,vector<node>,cmp> > mp; vector<vector<int>> res; if (root==NULL) return res; Q.push(make_pair(root,make_pair(0,0))); // pair的制作 mp[0].push(node(root->val,0)); while(!Q.empty()) { pair<TreeNode*,pair<int,int>> p=Q.front(); // pair的定义 Q.pop(); TreeNode* p1=p.first; pair<int,int> p2=p.second; if(p1->left!=NULL) { Q.push( make_pair(p1->left,make_pair(p2.first+1,p2.second-1))); mp[p2.second-1].push(node(p1->left->val,p2.first+1)); } if(p1->right!=NULL) { Q.push(make_pair(p1->right,make_pair(p2.first+1,p2.second+1))); mp[p2.second+1].push(node(p1->right->val,p2.first+1)); } } for(auto i: mp) { vector<int> subres; /*for(auto j:i.second) subres.push_back(j); */ // 说明优先队列,不能用这种方法遍历 while(!i.second.empty()) { subres.push_back(i.second.top().val); i.second.pop(); } res.push_back(subres); } return res; } };