220. 存在重复元素 III

题目描述

给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums[i] 和 nums[j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的
绝对值最大为 ķ。
示例 1:
输入: nums = [1,2,3,1], k = 3, t = 0
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1, t = 2
输出: true
示例 3:
输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false

方法1

常规思路,暴力法,直接遍历数组中的两个数对,进行判断

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {

    	int n = nums.size();
    	if(n < 2)
    		return false;
    	for(int i = 0;i < n;i++)//遍历的第一个数下标
    	{
    		for(int j = i+1;j < n && j-i<=k;j++)//遍历的第二个数下标



    			if(abs(nums[i]-nums[j])<=t)
    				return true;
    	}
    	return false;       
    }
};

方法2

利用set红黑树查找速度提高,利用set作为滑动窗口存储所有第一个满足候选的数,流式遍历第二个数,因为set中存储候选值a,它又位于绝对值中,所以必须拆开考虑。|b - a| <= t =>-t <= b - a <= t =>a <= b + t &&a >= b-t
auto iter = std::set::lower_bound(value=x);下界是参数value=x
返回指向第一个大于等于值x的元素的迭代器。

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {


    	int n = nums.size();
    	if(n < 2 || k < 0)
    		return false;
        set<long> s;
        for(int i = 0; i < n; i++) 
        {
        	if(i > k)
        		s.erase(nums[i-(k+1)]);
            auto it = s.lower_bound(nums[i] - long(t));//a >= b - t
            //*it <= nums[i] + long(t)由于怕溢出,写成下面的形式
            if(it!= s.end() && *it - nums[i] <= t)//a <= b + t 
            	return true;
            s.insert(nums[i]);
        }        
        return false;
    }
};

posted on 2021-05-05 10:27  朴素贝叶斯  阅读(62)  评论(0编辑  收藏  举报

导航