leetcode 987 二叉树的垂序遍历

image

题目解析

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

结果

image

posted @ 2021-08-01 15:08  抚琴思伯牙  阅读(92)  评论(0编辑  收藏  举报