题目解析

题目意思很简单,就是给你一个二叉树,然后告诉你每个节点都是有位置信息的,即每个节点可以用(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

算法实现

  1. 将二叉树转换成vector<pair<point,int>>
  2. 将上一步产生的容器排序
  3. 合并同一列的值组合成vector<vector<int>>
  4. 返回结果

代码

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 二叉树的垂序遍历的更多相关文章

  1. LeetCode:二叉树的后序遍历【145】

    LeetCode:二叉树的后序遍历[145] 题目描述 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很 ...

  2. [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 ...

  3. LeetCode 94. 二叉树的中序遍历(Binary Tree Inorder Traversal)

    94. 二叉树的中序遍历 94. Binary Tree Inorder Traversal 题目描述 给定一个二叉树,返回它的 中序 遍历. LeetCode94. Binary Tree Inor ...

  4. LeetCode 145. 二叉树的后序遍历(Binary Tree Postorder Traversal)

    145. 二叉树的后序遍历 145. Binary Tree Postorder Traversal 题目描述 给定一个二叉树,返回它的 后序 遍历. LeetCode145. Binary Tree ...

  5. Java实现 LeetCode 145 二叉树的后序遍历

    145. 二叉树的后序遍历 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成 ...

  6. Java实现 LeetCode 94 二叉树的中序遍历

    94. 二叉树的中序遍历 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? / ...

  7. LeetCode 145 二叉树的后序遍历(非递归)

    题目: 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路: 1 ...

  8. Leetcode 94. 二叉树的中序遍历

    1.问题描述 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 2.解法一 ...

  9. 【leetcode 145. 二叉树的后序遍历】解题报告

    前往二叉树的:前序,中序,后序 遍历算法 方法一:递归 vector<int> res; vector<int> postorderTraversal(TreeNode* ro ...

随机推荐

  1. 记一次项目中解决 -- 并发减库存超卖问题过程(Java)

    起因:项目中要做预约功能,首先每天的余票都是有上限的,自然不能出现超卖的情况 基于我们项目是单体分布式的springcloud部署,我想了下 第一种方法,直接mysql加行锁,要update这条库存数 ...

  2. SpringBoot和Spring到底有没有本质的不同?

    现在的Spring相关开发都是基于SpringBoot的.最后在打包时可以把所有依赖的jar包都打进去,构成一个独立的可执行的jar包.如下图: 使用java -jar命令就可以运行这个独立的jar包 ...

  3. 面试官:MySQL的可重复读级别能解决幻读问题吗?

    引言 之前在深入了解数据库理论的时候,了解到事务的不同隔离级别可能存在的问题.为了更好的理解所以在MySQL数据库中测试复现这些问题.关于脏读和不可重复读在相应的隔离级别下都很容易的复现了. 但是对于 ...

  4. DB2 SQL0805N解决和思考

    一.报错现象 这是一个在使用 DB2数据库过程中比较常见的错误, 报错信息如下 Exception stack trace: com.ibm.db2.jcc.am.SqlException: DB2 ...

  5. JAVA并行程序基础二

    JAVA并行程序基础二 线程组 当一个系统中,如果线程较多并且功能分配比较明确,可以将相同功能的线程放入同一个线程组里. activeCount()可获得活动线程的总数,由于线程是动态的只能获取一个估 ...

  6. 如何编写shell脚本

    1.首先创建一个目录 vi hello.sh 2.编写shell第一行 #!/bin/bash    (为了声明是shell脚本,第一行都要这么写) 3.可以添加注释     #the first p ...

  7. mysql left join转inner join

    在日常优化过程中,发现一个怪事情,同一个SQL出现两个完全不一样执行计划,left join 连驱动表都可以变成不一样. 对于left join,如果where条件里有被关联表过滤,left join ...

  8. 使用Git将代码上传至Gitee码云中

    Git是一个开源的分布式版本控制系统,可以高效处理任何或小或大的项目 Git与常用的版本控制工具CVS.Subversion 不同,Git采用了分布式版本库的方式,不必服务器端软件支持 Git与SVN ...

  9. MobileNet系列之MobileNet_v2

    ​ MobileNet系列之MobileNet_v1 Inception系列之Inception_v1 Inception系列之Batch Normalization Inception系列之Ince ...

  10. 10 一键部署LNMP网站平台

    #!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin NGINX_V=1.19.1 P ...