【问题标题】:Confusion about time complexity with hash maps对时间复杂度与哈希映射的混淆
【发布时间】:2021-03-05 13:34:59
【问题描述】:

在 leetcode 上,我发现“忽略”涉及哈希映射的最坏情况时间复杂度是很常见的。我认为在软件面试中,像他们经常做的那样假设“最坏情况”是标准的。以下是我对一个简单问题的解决方案。问题是在字符串中找到第一个不重复的字符。我知道哈希映射平均是 O(1) 查找.. 但是在遍历字符串并查找哈希映射时,为什么时间复杂度不是 O(N^2) 而是 O(N)?

#include <unordered_map>

class Solution {
public:
    unordered_map<char, int> m;
    
    int firstUniqChar(string s) {
        for(char c : s) {
            m[c]++;
        }
        for(int i =0; i < s.length(); i++) {
            if(m[s[i]] == 1) {
                return i;
            }
        }
        
        return -1;
    
    }
};

【问题讨论】:

    标签: c++ time-complexity


    【解决方案1】:

    平均为 O(N),因为哈希映射平均为 O(1) 每次查找,而您执行其中的 O(N)

    平均意味着对所有可能的输入进行平均。这意味着可能存在一个输入数组,它破坏了特定的哈希值并在每次查找时达到O(N) 或更差。

    最坏的情况在很大程度上是特定于实现的——例如散列到桶中取决于元素如何存储在每个桶中。如果它们在一个简单的列表中,则查找为O(&lt;duplicates&gt;),二叉树会将其归结为O(log&lt;duplicates&gt;)。搜索存在和丢失的键之间也可能存在差异。

    还有一个很大的假设是,所有散列容器都可以随着存储的元素数量而增长。 IE。保持桶的占用率低。

    在采访中提及他们最坏的情况并没有什么坏处,这表明你知道他们可以有限制。

    【讨论】:

    • 你是说真的在采访中,一般来说,平均情况就是它所说的,而不是最坏的情况?我明白为什么平均复杂度是 O(N)。
    • @JSman 更像是,能够区分它们是件好事。以快速排序为例,每个人都会说它在O(nlogn) 中运行,因为它通常会运行。但最坏的情况是O(n^2),除非你喜欢选择支点。如果你这样做,你将得到保证最佳的O(nlogn),但它在实践中没有被使用,因为它更慢。实际性能总是比任何渐近复杂度更重要,有时平均复杂度是更好的衡量标准。不要专注于面试问题,专注于理解,那么你就不会在乎他们问你什么。
    【解决方案2】:

    给定问题的时间复杂度为 O(N)。你可以为它提供一个perfect hash function,那就是永远不会发生冲突。这个完美的哈希函数是static_cast&lt;size_t&gt;(256+c)。好吧,如果你在 leetcode 上查看这个问题的最快解决方案,你会发现他们使用普通数组。


    【讨论】:

    • 考虑到只需要 26 个点,因此使用数组是有道理的。
    猜你喜欢
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 2020-11-19
    • 2011-04-26
    • 2013-07-20
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    相关资源
    最近更新 更多