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