[Leetcode]Contains Duplicate III

Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] andnums[j] is at mostt and the difference between i andj is at most k.

algorithm:

 brute force is straightforward,but it cannot pass the AC,time limit exceed

 code like below

class Solution {
public:
    /*algorithm: brute force 
        for number A[i], check A[i+1,i+k] ,whether there elements meets abs(nums[i]-nums[j]) <= t
        time O(n*k) space O(1)
    */
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        int n = nums.size();
        for(int i = 0;i < n-1;i++){
            for(int j = 1;j <= k && (i+j) < n;j++){
                if(abs(nums[i+j] - nums[i]) <= t)
                    return true;
            }
        }
        return false;
    }
};
class Solution {
public:
    /*algorimthm revised force algorithm
        1)first sort the array with index info attached.
        2)scan the array, compare i element with later element,reduce the compare times,
         time O(n^2) space O(n)
    */
    static bool cmp(const pair<int,int>&p1,const pair<int,int>&p2) { return (p1.first < p2.first);}
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        int n = nums.size();
        vector<pair<int,int> >pairs;
        for(int i = 0;i < n;i++)
            pairs.push_back(pair<int,int>(nums[i],i));
        sort(pairs.begin(),pairs.end(),cmp);
        
        for(int i = 0;i < n-1;++i){
            for(int j = i+1;j < n;){
                long vdiff = (long)pairs[j].first - (long)pairs[i].first;//overflow,use long instead of int
                int idiff = abs(pairs[j].second - pairs[i].second);
                if(vdiff > t)break;
                if(idiff > k)++j;
                else return true;
             }
        }
        return false;
    }
};
class Solution {
public:
    /*algorithm: hash solution
        we know |nums[i] - nums[j]| <= t     <=>    |nums[i]/t - nums[j]/t| <= 1
        time O(n) space O(t)
    */
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        int n = nums.size();
        unordered_map<int,long>tbl;
        int key;
        for(int i = 0;i < n;i++){
           key = nums[i]/max(1,t);
           int keys[]={key-1,key,key+1};
           for(int j = 0;j < 3;j++){
            if(tbl.count(keys[j]) && abs(nums[i] - tbl[keys[j]]) <= t)
              return true;
           }
           tbl[key] = nums[i];
           if(i >= k)
             tbl.erase(nums[i-k]/max(1,t)); 
         }
         return false;
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值