题目描述
给定二叉树,按垂序遍历返回其结点值。
对位于 (X, Y) 的每个结点而言,其左右子结点分别位于 (X-1, Y+1) 和 (X+1, Y+1)。
把一条垂线从 X = -infinity 移动到 X = +infinity ,每当该垂线与结点接触时,我们按从上到下的顺序报告结点的值( Y 坐标递增)。
如果两个结点位置相同,则首先报告的结点值较小。
按 X 坐标顺序返回非空报告的列表。每个报告都有一个结点值列表。
题解
题解1:递归
遍历所有的节点,然后对所有对节点进行排序。
每个节点对应一个坐标,遍历树并保存下每个节点的坐标值和节点值,当前节点坐标为(x, y),则其左子节点为(x-1, y+1),其右子节点为(x+1, y+1)。
对x进行升序排序,x相同的对y进行升序排序,y相同的对val进行升序排序, 把x相同的val分成一组。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
map<int, vector<pair<int, int>>> mp;//根据x坐标,存储y坐标和节点值
public:
vector<vector<int>> verticalTraversal(TreeNode* root) {
if(!root) return {};
vector<vector<int>> res;
dfs(root, 0, 0);
for(auto it : mp){
vector<int> temp;
sort(it.second.begin(), it.second.end());//map容器的迭代器里面有first 和 second. it.first会得到key, it.second会得到value。此处it.second得到包含y坐标和节点值的map.
for(auto cur : it.second) temp.push_back(cur.second);
res.push_back(temp);
}
return res;
}
void dfs(TreeNode* root, int x, int y){//前序遍历
if(!root) return;
mp[x].push_back({y, root->val});
dfs(root->left, x - 1, y + 1);
dfs(root->right, x + 1, y + 1);
}
};
复杂度分析
- 时间复杂度:O(NlogN),其中 N 指的是树的节点个数。
- 空间复杂度:O(N)。
题解2
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> verticalTraversal(TreeNode* root) {
if(!root){
return {};
}
map<int, vector<int>> records;
queue<pair<TreeNode*, int>> q;
q.push({root, 0});
while(!q.empty()){
int size = q.size();
map<int, vector<int>> tmp;
while(size--){
auto cur = q.front();
auto node = cur.first;
auto val = cur.second;
q.pop();
tmp[val].push_back(node->val);
if(node->left) q.push({node->left, val-1});
if(node->right) q.push({node->right, val+1});
}
for(auto& i : tmp){
int val = i.first;
sort(i.second.begin(), i.second.end());
for(auto j : i.second){
records[val].push_back(j);
}
}
}
vector<vector<int>> res;
for(auto i : records){
res.push_back(i.second);
}
return res;
}
};