zoukankan      html  css  js  c++  java
  • [LeetCode]Contains Duplicate

    题目:Contains Duplicate

    给定整数数组,查找数组是否包含任何重复项。 如果数组中的任何值至少出现两次,则函数应返回true,如果每个元素都不同,则返回false。

    思路:

    可以使用桶排序的思想来,遍历所有元素,通过元素值直接访问标志,当第一次遇到则设标志,第二次遇到就跳出循环。

    但是,这样空间复杂度很高,int有32位需要2^32byte;那么就可以考虑使用map;

    其实只需要知道有没有重复元素就可以,不一定要找到,可以有更简单的方法;使用set,将数组元素放入set,有重复元素只会存放一遍,最后比较长度就能知道有没有重复。

    bool LeetCode::containsDuplicate(vector<int>& nums){
        set<int>nondup(nums.begin(),nums.end());//保存所有所有元素一次,如果有重复则只保存一次
        return nondup.size() < nums.size();//有重复长度变短
    }

    题目:Contains DuplicateII

    这次是找数组的k个元素中是否有重复。

    思路:

    和上面类似,只是不需要整个数组,只顺序选其中k个元素。

    bool LeetCode::containsNearbyDuplicate(vector<int>& nums, int k){
        if (k >= nums.size() || nums.size() < 2){
            set<int>nondup(nums.begin(), nums.end());//保存所有所有元素一次,如果有重复则只保存一次
            return nondup.size() < nums.size();//有重复长度变短
        }
        auto head = nums.begin();
        auto tail = nums.begin() + k + 1;
        set<int>nondup(head, tail);
        while (tail != nums.end() && nondup.size() == k + 1){
            auto pos = nondup.find(*head);
            nondup.erase(pos);
            nondup.insert(*tail);
            ++head;
            ++tail;
        }
        if (nondup.size() <= k)return true;
        return false;
    }

    题目:Contains DuplicateIII

    这次是找数组的k个元素中是否有差的绝对值不超过的t的2个以上的元素。

    思路:

    知道使用lower_bound函数就能很快做出来,可以通过lower_bound找到set中满足x >= nums[i] - t的下界,这样就可以按照上面的思路来解决。

    bool LeetCode::containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t){
        set<long long>nondup;
        long long tL = t;
        for (size_t i = 0; i < nums.size();++i){
            if (i > k)nondup.erase(nums.at(i - k - 1));//k个元素以上时,每次删除第一个
            auto pos = nondup.lower_bound(nums.at(i) - t);//找到x >= nums[i] - t的下界
            if (pos != nondup.end() && *pos - nums.at(i) <= t)return true;//检测x <= nums[i] + t的上界
            nondup.insert(nums.at(i));//插入新的元素
        }
        return false;
    }

    思路2:

    要求差的绝对值<=t。可以用这样的算法来确定:

    假设有m和n满足上面的要求,则m/t = n/t或者m/t = n/t + 1或者m/t = n/t - 1;

    当n = k*t,m = k*t - a(0 < a < t)时,m/t = n/t - 1;

    这样就能按照前面的思路来求解,但是要注意一些特殊情况:

    1.负数的情况,可以减去MIN_INT;

    2.可能会溢出,使用long long类型;

    3.t < 0或k<1的情况。

    bool LeetCode::containsNearbyAlmostDuplicate2(vector<int>& nums, int k, int t){
        if (k < 1 || t < 0) return false;
        if (nums.size() < 2)return false;
        map<long long, long long>nondup;
        int MIN_INT = -2147483647 - 1;//不能直接将写-2147483648,因为便一起会先将2147483648转成int,再取负然后赋值
        long long tL = (long long)t + 1;
        for (size_t i = 0; i < nums.size(); ++i){
            long long value = ((long long)nums.at(i) - MIN_INT);
            long long bucket = value / tL;
            auto pre = nondup.find(bucket - 1);//n = k*tL m = k*tL - a;(0 < a < t)
            auto post = nondup.find(bucket + 1);//n = k*tL m = k*tL + a;(0 < a < t)
            if (nondup.find(bucket) != nondup.end() || (pre != nondup.end() && value - pre->second <= t) || (post != nondup.end() && post->second - value <= t))return true;
            if (i >= k){
                long long temp = ((long long)nums.at(i - k) - MIN_INT) / tL;
                nondup.erase(temp);//k个元素以上时,每次删除第一个
            }
            nondup[bucket] = value;//插入新的元素,通过n/(t+1)使t的间隔消失
        }
        return false;
    }
  • 相关阅读:
    ASP.NET Core 3.0 WebApi中使用Swagger生成API文档简介
    $.ajax
    C#使用RabbitMQ
    WebAPI+NLog实现接口调用日志输出
    Spire.Doc组件读取与写入Word
    .net中RabbitMQ生产者/消费者
    第2课
    第1课
    详解usbmon抓取的log各字段的含义
    使用 usbmon 抓取 usb 总线上的数据
  • 原文地址:https://www.cnblogs.com/yeqluofwupheng/p/6803172.html
Copyright © 2011-2022 走看看