Leetcode 987:二叉树的垂直顺序遍历:为啥我得到 TLE?

Posted

技术标签:

【中文标题】Leetcode 987:二叉树的垂直顺序遍历:为啥我得到 TLE?【英文标题】:Leetcode 987 :Vertical order traversal of binary tree : Why I am getting TLE?Leetcode 987:二叉树的垂直顺序遍历:为什么我得到 TLE? 【发布时间】:2020-08-07 11:53:26 【问题描述】:

我正在寻找 BFS 的垂直遍历。对于每个节点,我计算了它的水平距离。具有相同 hd 的节点将在垂直遍历中一起出现。对于根 hd 将为 0 。如果我们向左 hd = hd-1 ,对于右 hd = hd+1

/**
 * Definition for a binary tree node.
 * struct TreeNode 
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) 
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) 
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) 
 * ;
 */
class Solution 
public:
    vector<vector<int>> verticalTraversal(TreeNode* root) 
        vector<vector<int>> result;
        
        if(root==NULL)
            return result;
        
        queue<pair<TreeNode*,int>> myqueue;
        
        unordered_map<int,vector<int>> my_map;
        int hd=0;
        myqueue.push(make_pair(root,hd));
        
        while(!myqueue.empty())
        
            pair <TreeNode*,int> mypair = myqueue.front();
            myqueue.pop();
            hd = mypair.second;
            TreeNode* temp = mypair.first;
            my_map[hd].push_back(temp->val);
         //   myqueue.pop();
            if(temp->left!=nullptr)
                myqueue.push(make_pair(root->left,hd-1));
            if(temp->right!=nullptr)
                myqueue.push(make_pair(root->right,hd+1));
            
        
        
        //vector<temp>;
        unordered_map<int,vector<int>> :: iterator it;
        
        for(it=my_map.begin();it!=my_map.end();it++)
        
            vector<int> temp;
            for(int i=0;i<it->second.size();i++)
            
                temp.push_back(it->second[i]);
            
            result.push_back(temp);
        
        
        
        
        return result;
    
        
;

【问题讨论】:

【参考方案1】:

可能myqueue 永远不会被清空。

这是一个类似的 BFS,它会通过:

// This block might trivially optimize the exec time;
// Can be removed;

static const auto __optimize__ = []() 
    std::ios::sync_with_stdio(false);
    std::cin.tie(NULL);
    return 0;
();


// Most of headers are already included;
// Can be also removed;

#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
#include <map>


// Solution
static const struct Solution 
    static const struct Node 
        const TreeNode* node;
        const int x;
        const int y;
    ;

    static const std::vector<std::vector<int>> verticalTraversal(
                                   const TreeNode* root
    ) 
        std::vector<std::vector<int>> vertical_nodes;
        std::map<int, std::map<int, std::vector<int>>> mapvect;
        std::queue<Node*> nodes_q;
        nodes_q.push(new Noderoot, 0, 0);

        while (!nodes_q.empty()) 
            auto curr = nodes_q.front();
            nodes_q.pop();

            if (curr->node->left) 
                nodes_q.push(new Nodecurr->node->left, curr->x - 1, curr->y + 1);
            

            if (curr->node->right) 
                nodes_q.push(new Nodecurr->node->right, curr->x + 1, curr->y + 1);
            

            mapvect[curr->x][curr->y].emplace_back(curr->node->val);
        

        for (std::pair<int, std::map<int, std::vector<int>>> i : mapvect) 
            vertical_nodes.push_back();
            for (std::pair<int, std::vector<int>> j : i.second) 
                std::vector<int> vals = j.second;
                std::sort(std::begin(vals), std::end(vals));
                vertical_nodes.back().insert(
                    std::end(vertical_nodes.back()),
                    std::begin(vals),
                    std::end(vals)
                );
            
        

        return vertical_nodes;
    
;

这是一个 DFS,可能更容易实现:

// This block might trivially optimize the exec time;
// Can be removed;

const static auto __optimize__ = []() 
    std::ios::sync_with_stdio(false);
    std::cin.tie(NULL);
    return 0;
();

#include <cstdint>
#include <vector>
#include <map>
#include <set>

const static struct Solution 
    static std::vector<std::vector<int>> verticalTraversal(
                                          const TreeNode* root
    ) 
        std::vector<std::vector<int>> vertical_nodes;
        std::map<int, std::map<int, std::set<int>>> mapset;
        depthFirstSearch(root, 0, 0, mapset);
        for (auto x = std::begin(mapset); x != std::end(mapset); ++x) 
            vertical_nodes.emplace_back(std::vector<int>());
            for (auto y = std::begin(x->second); y != std::end(x->second); ++y) 
                vertical_nodes.back().insert(
                    std::end(vertical_nodes.back()),
                    std::begin(y->second),
                    std::end(y->second)
                );
            
        

        return vertical_nodes;
    

    static const void depthFirstSearch(
        const TreeNode* node,
        const int x,
        const int y,
        std::map<int, std::map<int, std::set<int>>>& mapset
    ) 
        if (node != NULL) 
            mapset[x][y].insert(node->val);
            depthFirstSearch(node->left, x - 1, y + 1, mapset);
            depthFirstSearch(node->right, x + 1, y + 1, mapset);
        
    
;

参考文献

更多详细信息,请参阅Discussion Board,您可以在其中找到大量解释清楚且公认的解决方案,其中包含多种languages,包括高效算法和渐近time/space 复杂性分析1,2.

【讨论】:

以上是关于Leetcode 987:二叉树的垂直顺序遍历:为啥我得到 TLE?的主要内容,如果未能解决你的问题,请参考以下文章

987. 二叉树的垂序遍历

987. 二叉树的垂序遍历

LeetCode 987. 二叉树的垂序遍历

二叉树的垂直顺序遍历中具有相同垂直高度的相同级别元素的问题

Leetcode刷题100天—102. 二叉树的层序遍历(二叉树)—day09

二叉树的垂直顺序遍历