220. 存在重复元素 III

Difficulty
Medium
Tags
滑动窗口
URL
https://leetcode.cn/problems/contains-duplicate-iii/
Star
给你一个整数数组 nums 和两个整数 kt 。请你判断是否存在 两个不同下标 ij,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k
如果存在则返回 true,不存在返回 false
示例 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
提示:
  • 0 <= nums.length <= 2 * 104
  • 231 <= nums[i] <= 231 - 1
  • 0 <= k <= 104
  • 0 <= t <= 231 - 1
通过次数79,393提交次数274,068

滑动窗口

思路
题目说了两个下标差值小于 k, 即限定了窗口大小为k, ,然后在窗口内寻找 最接当前新加入窗口的元素。判断,接近程度是否满足条件。
窗口采用有序数组,所以查找的时候用二分查找。总体复杂度为 nlogn
题解
from sortedcontainers import SortedList class Solution: def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool: l, r = 0, 0 wds = SortedList() while r < len(nums): if r > k: wds.remove(nums[r-k-1]) wds.add(nums[r]) # 找 nums[i] 的位置, 左边界右边界都可以 left, right = 0, len(wds)-1 while left <= right: mid = left + (right - left) // 2 if wds[mid] >= nums[r]: right = mid - 1 else: left = mid + 1 if left > 0 and abs(wds[left-1] - wds[left]) <= t or\ left < len(wds)-1 and abs(wds[left] - wds[left+1]) <= t: return True r += 1 return False