如果使用unordered_set,则O(NLogN)的性能要优于O(N)。

时间:2019-05-29 15:16:32

标签: c++ performance binary-search unordered-set

//Time sorting O(nlogn) + binary search for N items logN = 2NLogN = 
//Time: O(NLogN). 
//space - O(1).
bool TwoSum::TwoSumSortAndBinarySearch(int* arr, int size, int sum)
{
    sort(arr, arr + size);

    for (int i = 0; i < size; i++)
    {
        if (binary_search(arr + i + 1, arr + size, sum - arr[i]))
            return true;
    }
    return false;
}


//Time: O(N) as time complexity of Add and Search in hashset/unordered_set is O(1).
//Space: O(N)
bool TwoSum::TwoSumHashSet(int* arr, int size, int sum)
{
    unordered_set<int> hash;
    for (int i = 0; i < size; i++)
    {
        if (hash.find(sum - arr[i]) != hash.end())
            return true;
        hash.insert(arr[i]);
    }
    return false;
}

int* TwoSum::Testcase(int size)
{
    int* in = new int[size];
    for (int i = 0; i < size; i++)
    {       
        in[i] = rand() % (size + 1);//random number b/w 0 to N.
    }
    return in;
}

int main()
{
    int size = 5000000;
    int* in = TwoSum::Testcase(size);

    auto start = std::chrono::system_clock::now();//clock start 
    bool output = TwoSum::TwoSumHashSet(in, size, INT_MAX);
    auto end = std::chrono::system_clock::now();//clock end

    std::chrono::duration<double> elapsed_seconds = end - start;
    cout << "elapsed time: " << elapsed_seconds.count() << "s\n";   
}

我测量了以上两种方法的性能,在这里我想找到TwoSum问题。 在第一种方法中,我先对数组进行排序,然后使用二进制搜索。 时间:O(NLogN)。 空间-O(1)。

在第二种方法中,使用unordered_set,其复杂度平均是恒定的,最坏的情况是容器大小呈线性。

// Time:O(N),因为哈希集/ unordered_set中“添加”和“搜索”的时间复杂度为O(1)。 //空格:O(N)

这是这两种方法花费的三个运行时间

TwoSumSortAndBinarySearch --------------- TwoSumHashSet


  1. 8.05 --------------------------------------- 15.15

  1. 7.76 --------------------------------------- 14.47

  1. 7.74 --------------------------------------- 14.28

因此,很明显,TwoSumSortAndBinarySearch的性能肯定优于unordered_Set。

哪种方法更可取,并在实际情况下建议使用?为什么?

1 个答案:

答案 0 :(得分:0)

这是因为计算复杂性并未考虑每台现代计算机中存在的多级存储系统的行为。正是因为您使用时间(!!)通过代理来度量该行为,所以度量并不像理论上的计算复杂性那样。 计算复杂度只能在代码非常适合平台的情况下,在非常受控制的情况下预测执行时间。如果要衡量复杂性,就无法衡量时间。测量操作计数。那时它将与理论相符。

根据我有限的经验,当行为既不是指数也不是三次(或更高项)时,计算复杂性理论很难预测合理大小的数据集的运行时间。在计算复杂性发挥作用之前,缓存访问模式和体系结构并行性的利用是性能的主要预测指标。