为什么矢量比unordered_map快?

Omk*_*kar 6 c++ algorithm dictionary unordered-map vector

我正在解决LeetCode上的问题,但是没有人能够解释我的问题。

问题是这样的:

给定一个任意的赎金票据字符串和另一个包含所有杂志字母的字符串,编写一个函数,如果可以从杂志中构造赎金票据,则该函数将返回true;否则,它将返回false。

杂志字符串中的每个字母只能在赎金记录中使用一次。

注意:您可以假定两个字符串都只包含小写字母。

canConstruct("a", "b") -> false
canConstruct("aa", "ab") -> false
canConstruct("aa", "aab") -> true
Run Code Online (Sandbox Code Playgroud)

我的代码(需要32毫秒):

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        if(ransomNote.size() > magazine.size()) return false;
        unordered_map<char, int> m;

        for(int i = 0; i < magazine.size(); i++)
            m[magazine[i]]++;

        for(int i = 0; i < ransomNote.size(); i++)
        {
            if(m[ransomNote[i]] <= 0) return false;
            m[ransomNote[i]]--;
        }
        return true;
    }
};
Run Code Online (Sandbox Code Playgroud)

代码(我不知道为什么会更快-需要19毫秒):

bool canConstruct(string ransomNote, string magazine) {
        int lettersLeft = ransomNote.size(); // Remaining # of letters to be found in magazine
        int arr[26] = {0};
        for (int j = 0; j < ransomNote.size(); j++) {
            arr[ransomNote[j] - 'a']++; // letter - 'a' gives a value of 0 - 25 for each lower case letter a-z
        }

        int i = 0;
        while (i < magazine.size() && lettersLeft > 0) {
            if (arr[magazine[i] - 'a'] > 0) {
                arr[magazine[i] - 'a']--;
                lettersLeft--;
            }
            i++;
        }
        if (lettersLeft == 0) {
            return true;
        } else {
            return false;
        }
    }
Run Code Online (Sandbox Code Playgroud)

两者都具有相同的复杂性,并且使用相同的结构来解决问题,但是我不明白为什么一个时间要比另一个时间花费几乎两倍的时间。查询向量的时间为O(1),但对于unordered_map而言相同。向其中一个添加条目/键的情况相同。

拜托,有人可以解释一下为什么运行时间变化如此之大吗?

ili*_*lim 6

首先要注意的是,尽管查询an的平均时间unordered_map是恒定的,但最坏的情况不是O(1)。如您所见它实际上升至的顺序O(N)N表示容器的大小。

其次,由于vector分配了内存的顺序部分,即使在最坏的情况下,访问该内存也非常高效并且实际上恒定的。(即简单的指针算术,而不是计算更复杂的哈希函数的结果)还可能涉及顺序内存的各种缓存级别(即,取决于您的代码运行的平台),与使用vector相比,使用可以更快地执行代码unordered_map

从本质上讲,就复杂性而言,a的最坏情况下的性能vector比的效率更高unordered_map。最重要的是,大多数硬件系统都提供了诸如缓存之类的功能,这些功能使使用范围vector更大。(即O(1)操作中较小的恒定因素)