为什么我的答案被 set 接受但不被 vector 接受?

发布于 2025-01-12 23:48:04 字数 842 浏览 2 评论 0原文

问题是我们必须查找是否存在总和为零的子数组。如果可能则返回 true,否则返回 false。 时间限制:3秒

这是使用无序集被接受的代码。

bool subArrayExists(int arr[], int n)
    {
        //Your code here
        int sum=0;
        unordered_set<int>s;
        for(int i=0;i<n;i++){
            sum=sum+arr[i];
            if(sum==0||s.find(sum)!=s.end()){
               return true;
            }
            s.insert(sum);
        }
        return false;
    }

这是给出 tle 的向量解。

bool subArrayExists(int arr[], int n)
    {
        //Your code here
        int sum=0;
        vector<int>v;
        for(int i=0;i<n;i++){
            sum=sum+arr[i];
            if(sum==0||find(v.begin(),v.end(),sum)!=v.end()){
                return true;
            }
            v.push_back(sum);
        }
        return false;
    }

Question is We have to find if there is any sub array whose sum is zero.Return true if possible and false if not.
Time contraint:3 seconds

This is the code using unordered set getting accepted .

bool subArrayExists(int arr[], int n)
    {
        //Your code here
        int sum=0;
        unordered_set<int>s;
        for(int i=0;i<n;i++){
            sum=sum+arr[i];
            if(sum==0||s.find(sum)!=s.end()){
               return true;
            }
            s.insert(sum);
        }
        return false;
    }

This is the vector solution which is giving tle.

bool subArrayExists(int arr[], int n)
    {
        //Your code here
        int sum=0;
        vector<int>v;
        for(int i=0;i<n;i++){
            sum=sum+arr[i];
            if(sum==0||find(v.begin(),v.end(),sum)!=v.end()){
                return true;
            }
            v.push_back(sum);
        }
        return false;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

久伴你 2025-01-19 23:48:04

这一行

if(sum==0||s.find(sum)!=s.end()){

与这一行非常不同,

if(sum==0||find(v.begin(),v.end(),sum)!=v.end()){

首先,unordered_set 不会存储相同的元素两次。一般来说,这会产生影响,尽管当您遇到第一个重复项时停止,向量和集合中的元素数量在这里是相同的。

接下来,std::unordered_set::find 具有平均恒定复杂度,而 std::find 是线性的。 std::unordered_set::find 可以利用集合的内部结构,这就是它存在的原因。您不想将 std::find 与无序集一起使用,因为那样会降低性能。对于无序集,您的算法为 O(N),向量为 O(1 + 2 + 3 + ... + N),即 O (N^2)

请注意,具有无序集的版本可以做得更快。目前您正在搜索该元素两次。一次是在这里 s.find(sum) ,另一次是在插入它时。当您使用 unodered_set::insert 的返回值时,您可以同时执行这两项操作。它返回一对迭代器(指向元素)和一个指示元素是否已插入的布尔值。当该 boolfalse 时,该元素之前已经存在:

        sum=sum+arr[i];
        auto ret = s.insert(sum);
        if(sum==0 || ret.second == false){
           return true;
        }

This line

if(sum==0||s.find(sum)!=s.end()){

is very different from this line

if(sum==0||find(v.begin(),v.end(),sum)!=v.end()){

First, a unordered_set does not store the same element twice. In general this would make a difference, though as you stop when you encounter the first duplicate, the number of elements in the vector and in the set are the same here.

Next, std::unordered_set::find has average constant complexity while std::find is linear. std::unordered_set::find can make use of the internal structure of the set, thats why it exists in the first place. You don't want to use std::find with a unordered set, because that would be less performant. With the unordered set your algorithm is O(N) with the vector it is O(1 + 2 + 3 + ... + N) which is O(N^2).

Note that the version with the unodered set could be made even faster. Currently you are searching the element twice. Once here s.find(sum) and another time when inserting it. You could do it both at once when you use the return value from unodered_set::insert. It returns a pair of an iterator (pointing to the element) and a bool that indicates whether the element was inserted. When that bool is false, the element was already present before:

        sum=sum+arr[i];
        auto ret = s.insert(sum);
        if(sum==0 || ret.second == false){
           return true;
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文