题目链接:https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree/
题意:
给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。
对位于 (row, col) 的每个结点而言,其左右子结点分别位于 (row + 1, col - 1) 和 (row + 1, col + 1) 。树的根结点位于 (0, 0) 。
二叉树的 垂序遍历 从最左边的列开始直到最右边的列结束,按列索引每一列上的所有结点,形成一个按出现位置从上到下排序的有序列表。如果同行同列上有多个结点,则按结点的值从小到大进行排序。
返回二叉树的 垂序遍历 序列。
方法:哈希表中再加哈希表,不用哈希表中加一个vector的原因是,如果一个树,不是完全二叉树,而是类似于一条链,这样子vector要开的很大,会浪费大量的空间,如果题目有说完全二叉树,那样就可以使用vector,而且省空间
/**
* 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 {
private:
map<int,map<int,vector<int>>> mp;//按序排序的哈希表,<列号,<行号,里面的数字>>,哈希表中再包含一个哈希表
public:
void dfs(TreeNode* node,int col,int row)
{
mp[col][row].emplace_back(node->val);//更新哈希值
//深搜左节点
if(node->left!=nullptr)//左节点不为空
{
dfs(node->left,col-1,row+1);
}
//深搜右节点
if(node->right!=nullptr)//右节点不为空
{
dfs(node->right,col+1,row+1);
}
}
vector<vector<int>> verticalTraversal(TreeNode* root) {
vector<vector<int>> ret;//要返回的向量
// vector<int> tmp;
dfs(root,0,0);//深度搜索
map<int,map<int,vector<int>>>::iterator iter;//指定迭代器
for(iter = mp.begin();iter!=mp.end();iter++)//遍历哈希表
{
vector<int> vct;//之当一个向量用来返回
map<int,vector<int>>::iterator iter1 = iter->second.begin();//用来遍历哈希表中的哈希表
while(iter1!=iter->second.end())//遍历哈希表中的哈希表
{
vector<int> tmp=iter1->second;//因同一行,同一列可能存在多个元素,所以必须用向量存储可能存在的多个元素
sort(tmp.begin(),tmp.end());//从小到大排序
vct.insert(vct.end(),tmp.begin(),tmp.end());//在一个vector中插入另一个vector,将tmp插到vct的尾部
iter1++;//更新迭代器
}
ret.emplace_back(vct);//更新返回向量
}
return ret;
}
};
调整数据结构优化
/**
* 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 {
private:
map<int,vector<pair<int,int>>> mp;//按序排序的哈希表,<列号,<行号,里面的数字>>,哈希表中再包含一个哈希表
public:
void dfs(TreeNode* node,int col,int row)
{
mp[col].push_back({row,node->val});//更新哈希值
//深搜左节点
if(node->left!=nullptr)//左节点不为空
{
dfs(node->left,col-1,row+1);
}
//深搜右节点
if(node->right!=nullptr)//右节点不为空
{
dfs(node->right,col+1,row+1);
}
}
vector<vector<int>> verticalTraversal(TreeNode* root) {
vector<vector<int>> ret;//要返回的向量
dfs(root,0,0);//深度搜索
map<int,vector<pair<int,int>>>::iterator iter;//指定迭代器
for(iter = mp.begin();iter!=mp.end();iter++)//遍历哈希表
{
vector<int> vct;//之当一个向量用来返回
sort(iter->second.begin(),iter->second.end());
for(auto& elem:iter->second)
{
vct.emplace_back(elem.second);
}
ret.emplace_back(vct);//更新返回向量
}
return ret;
}
};
三元组+自定义排序(效果最优)
/**
* 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 {
//自定义排序
private:
vector<tuple<int,int,int>> vct;//三元组,<列号,行号,里面的数字>
public:
void dfs(TreeNode* node,int col,int row)
{
vct.emplace_back(col,row,node->val);//更新三元组
//深搜左节点
if(node->left!=nullptr)//左节点不为空
{
dfs(node->left,col-1,row+1);
}
//深搜右节点
if(node->right!=nullptr)//右节点不为空
{
dfs(node->right,col+1,row+1);
}
}
vector<vector<int>> verticalTraversal(TreeNode* root) {
vector<vector<int>> ret;//要返回的向量
dfs(root,0,0);//深度搜索
//升序排序三元组中的内容
sort(vct.begin(),vct.end());
int lastCol=INT_MIN;//记录上一各元素的列值
vector<int> tmp;//暂存数字
for(auto &[col,row,val]:vct)
{
if(col!=lastCol)//如果不同,把向量中的值打进要返回的向量,刷新向量
{
if(lastCol!=INT_MIN)//排除掉刚开始的那种情况
ret.emplace_back(tmp);
lastCol = col;
tmp.clear();
}
tmp.emplace_back(val);
}
ret.emplace_back(tmp);//插入最后一次的向量
return ret;
}
};