220存在重复元素 III(滑动窗口+哈希表)

1、题目描述

在整数数组 nums 中,是否存在两个下标 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值小于等于 t ,且满足 i 和 j 的差的绝对值也小于等于 ķ 。

如果存在则返回 true,不存在返回 false。

2、示例

输入: nums = [1,2,3,1], k = 3, t = 0
输出: true

输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false

3、题解

解法一:

基本思想:滑动窗口+哈希表,用哈希表来维护这个k大小的滑动窗口,如果下一个插入的元素与插入位置的左右两边元素绝对值小于等于t,返回true,否则加入到滑动窗口,同时滑动窗口去掉最旧的元素。

解法二:

基本思想:滑动窗口 + multiset,滑动窗口大小为k,遍历nums所有元素

  • 如果滑动窗口大小小于等于k,插入当前的元素,同时比较插入的元素与左右两边元素的绝对值差是否小于等于t返回true
  • 如果滑动窗口大小大于k,multiset去除左边界元素,同时滑动窗口左边界右移。
#include<algorithm>
#include<iostream>
#include<vector>
#include <iterator>
#include<set>
using namespace std;
class Solution {
public:
	bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
		//基本思想:滑动窗口+哈希表,用哈希表来维护这个k大小的滑动窗口
		//如果下一个插入的元素与插入位置的左右两边元素绝对值小于等于t,返回true,否则加入到滑动窗口,同时滑动窗口去掉最旧的元素
		set<long> container;  //防止两数相减超出int范围
		for (int i = 0; i < nums.size(); i++)
		{
			auto iter = container.lower_bound(nums[i]);
			if (iter != container.end() && *iter - nums[i] <= t)
				return true;
			if (iter != container.begin() && nums[i] - *(--iter) <= t)
				return true;
			container.insert(nums[i]);
			if (container.size() > k)
				container.erase(nums[i - k]);
		}
		return false;
	}
};
class Solution1 {
public:
	bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
		//基本思想:滑动窗口 + multiset,滑动窗口大小为k,遍历nums所有元素
		//如果滑动窗口大小小于等于k,插入当前的元素,同时比较插入的元素与左右两边元素的绝对值差是否小于等于t返回true
		//如果滑动窗口大小大于k,multiset去除左边界元素,同时滑动窗口左边界右移。
		if (nums.size() == 0)
			return false;
		multiset<int> container;
		int left = 0, right = 1;
		long long value1, value2;
		container.insert(nums[left]);
		while (right < nums.size())
		{
			if (right - left <= k)
			{
				auto iter = container.insert(nums[right]);
				if (iter != container.begin())
				{
					value2 = *iter;
					auto iter1 = iter;
					value1 = *(--iter1);
					if (value2 - value1 <= t)
						return true;
				}
				if (iter != --container.end())
				{
					value1 = *iter;
					value2 = *(++iter);
					if (value2 - value1 <= t)
						return true;
				}
				right++;
			}
			else
			{
				container.erase(container.find(nums[left]));
				left++;
			}
		}
		return false;
	}
};
int main()
{
	Solution solute;
	vector<int> nums = { 3,6,0,4 };
	int k = 2, t = 2;
	cout << solute.containsNearbyAlmostDuplicate(nums, k, t) << endl;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值