终于做到了这一题,发现这一题不是这么好做,细节有点多。
首先,考虑bfs还是dfs。因为会有重叠,选用bfs。
然后考虑怎么确定每个点在哪一列当中,我们记录每个点它的x(以root的x为0),然后记录x为0的那一列的index是多少,然后可以确定下来。
ok,然后我们层序遍历,需要注意重叠的情况,重点是重叠的情况:
1.可能不止两个会重叠在一起。
2.普通的层序遍历,重叠在一起的不一定会在queue中挨在一起。如果两个点重叠,那么它们的左子树也是重叠的,但是不会在一起,因为第一个的右子树在中间。
第二点是重中之重,所以我们在每一层遍历时,都需要排序,按照x由小到大的顺序。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> verticalTraversal(TreeNode* root) {
vector<vector<int>> res;
queue<pair<int, TreeNode*>> q;
//queue<pair<int, int>> pos;
if (root) {
q.push(make_pair(0, root));
}
int rootIdx = -1;
int x;
while (!q.empty()) {
sortHelper(q);
int sz = q.size();
int lastX = INT_MIN;
int cnt = 0;//可能不止一个点会重叠,而且x相等的不一定会挨在一起,比如两个重叠的它们的左子树就不会挨在一起,应该使用vector<pair<int, TreeNode*>>这个来,每次需要重新排序
while (sz-- > 0) {
auto node = q.front().second;
x = q.front().first;
q.pop();
//cout << x << " " << y << " " << node->val << endl;
int idx = rootIdx + x;
if (idx < 0) {
res.insert(res.begin(), vector<int>());
++rootIdx;
} else if (idx == res.size())
res.push_back(vector<int>());
idx = rootIdx + x;
res[idx].push_back(node->val);
if (x == lastX) {
int sz = res[idx].size();
int i = sz-1;
while (i > sz-1-cnt && res[idx][i] < res[idx][i-1]) {
swap(res[idx][i], res[idx][i-1]);
--i;
}
++cnt;
} else {
lastX = x;
cnt = 1;
}
if (node->left) {
q.push(make_pair(x-1, node->left));
}
if (node->right) {
q.push(make_pair(x+1, node->right));
}
}
}
return res;
}
private:
void sortHelper(queue<pair<int, TreeNode*>>& q) {
vector<pair<int, TreeNode*>> vec;
while (!q.empty()) {
vec.push_back(q.front());
q.pop();
}
sort(vec.begin(), vec.end());
int i = 0;
while (i < vec.size()) {
q.push(vec[i++]);
}
}
};
//用x,y,rootindx控制是哪一竖列
//然后层序遍历。然后如果一个和上一个是同一数列,就需要比较一下大小
这里写的不太好,应该用两个vector<pair<int, TreeNode*>>> 来做会好一些,但是懒得改了。