leetcode 987 二叉树的垂序遍历

题目解析
题目意思很简单,就是给你一个二叉树,然后告诉你每个节点都是有位置信息的,即每个节点可以用(x,y)来表示。然后节点位置信息为(x,y)的节点的左节点位置为(x+1,y-1),右节点位置为(x+1,y+1)。并且根节点的位置信息统一为(0,0)
现在你需要像扫描表格一样,从上往下,从左往右的顺序遍历。
解题思路
要求的顺序是从上往下,从左往右,并且如果位置相同,就按节点值从小到大排。那么能决定顺序的就是两个信息,一个是节点的坐标信息,一个是节点的值信息。显然是需要对一个pair<坐标,节点值>进行排序。其中坐标可以用一个point(x,y)来表示。
排序规则
pair类型有一个默认排序规则,就是先比较first,如果first相等,则再比较second。
正好符合"如果位置相同,就按节点值从小到大排"的约定
point的比较,需要满足“从上往下,从左往右”的约定
所以应该是先比较point.y,然后再比较point.x
算法实现
- 将二叉树转换成
vector<pair<point,int>> - 将上一步产生的容器排序
- 合并同一列的值组合成
vector<vector<int>> - 返回结果
代码
class point
{
public:
int x;
int y;
point(int _x, int _y) :x(_x), y(_y) {};
};
bool operator<(const point& left,const point& right)
{
return (left.y < right.y) || (left.y == right.y) && (left.x < right.x);
}
bool operator==(const point& left, const point& right)
{
return (left.x == right.x && left.y == right.y);
}
ostream& operator<<(ostream& output, const point& p) // 打印输出,以便查看
{
output << "(" << p.x << "," << p.y << ")";
return output;
}
bool PairCompare(const pair<point, int>& left, const pair<point, int>& right)
{
return (left.first < right.first) || ((left.first == right.first) && (left.second < right.second));
}
class Solution {
vector<pair<point, int>> vec;
void bfs(TreeNode* node, point p)
{
if (!node)
return;
bfs(node->left, point(p.x + 1, p.y - 1));
vec.push_back(make_pair(p, node->val));
bfs(node->right, point(p.x + 1, p.y + 1));
}
public:
vector<vector<int>> verticalTraversal(TreeNode* root) {
vector<vector<int>> ans;
if (!root)
return ans;
bfs(root, point(0, 0));
sort(vec.begin(), vec.end(), PairCompare);
/* 输出排序结果
for (auto x : vec)
{
cout << "point: " << x.first;
cout << "val: " << x.second << endl;
}
*/
auto prePair = vec.begin();
vector<int> tmpVec;
tmpVec.push_back(prePair->second);
for (auto it = vec.begin() + 1; it != vec.end(); ++it)
{
if (it->first.y == prePair->first.y)
{
tmpVec.push_back(it->second);
}
else
{
ans.push_back(tmpVec);
tmpVec.clear();
tmpVec.push_back(it->second);
prePair = it;
}
}
ans.push_back(tmpVec);
return ans;
}
};
结果

leetcode 987 二叉树的垂序遍历的更多相关文章
- LeetCode:二叉树的后序遍历【145】
LeetCode:二叉树的后序遍历[145] 题目描述 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很 ...
- [Swift]LeetCode987. 二叉树的垂序遍历 | Vertical Order Traversal of a Binary Tree
Given a binary tree, return the vertical order traversal of its nodes values. For each node at posit ...
- LeetCode 94. 二叉树的中序遍历(Binary Tree Inorder Traversal)
94. 二叉树的中序遍历 94. Binary Tree Inorder Traversal 题目描述 给定一个二叉树,返回它的 中序 遍历. LeetCode94. Binary Tree Inor ...
- LeetCode 145. 二叉树的后序遍历(Binary Tree Postorder Traversal)
145. 二叉树的后序遍历 145. Binary Tree Postorder Traversal 题目描述 给定一个二叉树,返回它的 后序 遍历. LeetCode145. Binary Tree ...
- Java实现 LeetCode 145 二叉树的后序遍历
145. 二叉树的后序遍历 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成 ...
- Java实现 LeetCode 94 二叉树的中序遍历
94. 二叉树的中序遍历 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? / ...
- LeetCode 145 二叉树的后序遍历(非递归)
题目: 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路: 1 ...
- Leetcode 94. 二叉树的中序遍历
1.问题描述 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 2.解法一 ...
- 【leetcode 145. 二叉树的后序遍历】解题报告
前往二叉树的:前序,中序,后序 遍历算法 方法一:递归 vector<int> res; vector<int> postorderTraversal(TreeNode* ro ...
随机推荐
- 记一次项目中解决 -- 并发减库存超卖问题过程(Java)
起因:项目中要做预约功能,首先每天的余票都是有上限的,自然不能出现超卖的情况 基于我们项目是单体分布式的springcloud部署,我想了下 第一种方法,直接mysql加行锁,要update这条库存数 ...
- SpringBoot和Spring到底有没有本质的不同?
现在的Spring相关开发都是基于SpringBoot的.最后在打包时可以把所有依赖的jar包都打进去,构成一个独立的可执行的jar包.如下图: 使用java -jar命令就可以运行这个独立的jar包 ...
- 面试官:MySQL的可重复读级别能解决幻读问题吗?
引言 之前在深入了解数据库理论的时候,了解到事务的不同隔离级别可能存在的问题.为了更好的理解所以在MySQL数据库中测试复现这些问题.关于脏读和不可重复读在相应的隔离级别下都很容易的复现了. 但是对于 ...
- DB2 SQL0805N解决和思考
一.报错现象 这是一个在使用 DB2数据库过程中比较常见的错误, 报错信息如下 Exception stack trace: com.ibm.db2.jcc.am.SqlException: DB2 ...
- JAVA并行程序基础二
JAVA并行程序基础二 线程组 当一个系统中,如果线程较多并且功能分配比较明确,可以将相同功能的线程放入同一个线程组里. activeCount()可获得活动线程的总数,由于线程是动态的只能获取一个估 ...
- 如何编写shell脚本
1.首先创建一个目录 vi hello.sh 2.编写shell第一行 #!/bin/bash (为了声明是shell脚本,第一行都要这么写) 3.可以添加注释 #the first p ...
- mysql left join转inner join
在日常优化过程中,发现一个怪事情,同一个SQL出现两个完全不一样执行计划,left join 连驱动表都可以变成不一样. 对于left join,如果where条件里有被关联表过滤,left join ...
- 使用Git将代码上传至Gitee码云中
Git是一个开源的分布式版本控制系统,可以高效处理任何或小或大的项目 Git与常用的版本控制工具CVS.Subversion 不同,Git采用了分布式版本库的方式,不必服务器端软件支持 Git与SVN ...
- MobileNet系列之MobileNet_v2
MobileNet系列之MobileNet_v1 Inception系列之Inception_v1 Inception系列之Batch Normalization Inception系列之Ince ...
- 10 一键部署LNMP网站平台
#!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin NGINX_V=1.19.1 P ...