【问题标题】:Why is this soln faster than the other?为什么这个解决方案比另一个解决方案快?
【发布时间】:2021-05-20 17:30:55
【问题描述】:

问题是 Leetcode 的 N-Repeated Element in Size 2N Array

在一个大小为 2N 的数组 A 中,有 N+1 个唯一元素,其中恰好一个元素重复了 N 次。

返回重复N次的元素。

我很困惑,请帮忙!

更快的代码

    class Solution {
public:
    int repeatedNTimes(vector<int>& A) {
        auto it = A.begin();
        while(it!=A.end())
        {
            if(count(A.begin(),A.end(),*it)>1)
            {
                break;
            }
            else
                it++;              
        }
        return *it;
    }
};

较慢的代码

    class Solution {
public:
    int repeatedNTimes(vector<int>& A) {
        unordered_map<int,int> u;
        int rep;
        for(auto i: A){
            u[i]++;
            if(u[i]>1){
                rep=i;
            }
        }
        
        return rep;
    }
};

【问题讨论】:

  • 这两种解决方案似乎都不是最优的,但第一个解决方案的一个优点是它一旦找到解决方案就会停止查找。这种改进可以很容易地添加到第二个,你为什么不试试呢。
  • unordered_map 中的插入/查找可能平均在恒定时间,但这并不意味着它不需要相当长的时间(与其他操作相比)。在这种情况下,给定输入集的速度比其他解决方案慢,即使该解决方案的时间复杂度更差。顺便说一句:第二个解决方案计算所有元素的频率,即使找到了出现次数超过 1 的元素;当一次就足够时进行两次查找也无济于事;此外,unordered_set 也可以解决问题。
  • @john 谢谢你的回复,那么它的最佳解决方案是什么?
  • @fabian 是的,我现在明白了unordered_map 将需要更多时间来插入元素。感谢您的回复!
  • @doggone_boy 我改变了主意。鉴于 50% 的元素是重复的,两个重复的元素必须是相邻的,或者重复的元素必须在整个数组中交替出现。您可以通过对整个阵列的单次扫描来检查这两种可能性。即使在最坏的情况下,这也是一种线性时间算法,不需要任何额外的数据结构

标签: c++ arrays hashmap unordered-map


【解决方案1】:

这里有一些使用上述方法的(未经测试的)代码。我确实假设输入数据是所描述的形式。如果不是这种情况,此代码将出错。

class Solution
{
public:
    int repeatedNTimes(vector<int>& A) {
        // check for alternating elements at even indexes
        if (A[0] == A[2])
           return A[0];
        // check for alternating elements at odd indexes
        if (A[1] == A[3])
           return A[1];
        // check for first and last being the same
        if (A.front() == A.back())
           return A.front();
        // check adjacent elements
        for (size_t i = 0;; ++i)
        {
            if (A[i] == A[i + 1])
                return A[i];
        }
        return -1;
    }
};

编辑

想到一个错误,我的算法只有在邻接环绕时才有效,即第一个和最后一个元素也被认为是相邻的。我也添加了代码来检查这种可能性。

【讨论】:

  • 您的整个 for 循环可能是对 std::adjacent_find 的调用。
  • @john 这个解决方案真的更快!谢谢大佬!
  • @DrewDormann 你能解释一下它的作用吗?谢谢!
  • @doggone_boy 不在这些 cmets 中,抱歉。这里不是问新问题的地方。
  • @doggone_boy std::adjacent_find 和我的循环差不多。它查找相邻的相等元素并将迭代器返回到它找到的第一个此类元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多