987. Vertical Order Traversal of a Binary Tree

在这里插入图片描述

终于做到了这一题,发现这一题不是这么好做,细节有点多。

首先,考虑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*>>> 来做会好一些,但是懒得改了。

posted @ 2019-10-24 16:14  于老师的父亲王老爷子  阅读(12)  评论(0编辑  收藏  举报