此代码段的时间复杂度

时间:2018-05-06 22:05:48

标签: c++ tree

我正在从LeetCode.com解决以下问题:

  

给定二叉树,返回其节点值的Z字形级别遍历。 (即,从左到右,然后从右到左进行下一级别的交替)。

对于树:

    3
   / \
  9  20
    /  \
   15   7

答案是:

[
  [3],
  [20,9],
  [15,7]
]

我想出了以下代码:

/**
 * 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>> result;

    void zigzagLevelOrderUtil(TreeNode* root, int level) {
        if(root==NULL) return;

        if(result.size()==level)
            result.push_back(vector<int>());

        result[level].push_back(root->val);
        zigzagLevelOrderUtil(root->left, level+1);
        zigzagLevelOrderUtil(root->right, level+1);
    }

    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        result.clear();
        zigzagLevelOrderUtil(root, 0);

        for(int i=0; i<result.size(); i++)
            if(i%2!=0)
                reverse(result[i].begin(), result[i].end());        //I think the complexity here is O(hn)

        return result;
    }
};

但是,我不确定复杂性 - 它是O(hn)(其中h是高度,n是节点数);还是只是O(h)。我很困惑,因为从技术上讲,我只在h的一半工作(逆转);我认为它可以有最多n/2个节点。 [请参阅代码中的评论]。

有人可以确认一下吗?谢谢!

1 个答案:

答案 0 :(得分:0)

让我们看看。

由于结果向量中有h个元素,可以说复杂度为O(h.n),但实际上它是O(n)。

为什么?因为&#39; std :: reverse&#39;函数具有O(n)复杂度。看起来像是O(h.n),因为你在结果向量中有大量的向量。但是请记住,所有向量都有n个元素,这些元素是树的节点。

假设我们有一个包含3个级别的完整二叉树,包括根级别。结果向量类似于[[x],[y,z],[t,w,m,n]]。结果[0]的操作为1,内向量0为1,结果[1]为1,内向量为1,结果[2]为1,内向量为4,因此我们有10个相等的运算到h + n次操作。 (为了简化我们的工作,不仅处理了索引,而且所有索引都已处理完毕。)

随着内部向量变大,我们进入下向外向量索引的操作变得微不足道。时间复杂度是O(h + n),如示例中所示,但是h <1。我们可以说它是O(n)的复杂性。