Leetcode 2026-08-21 题目分享
LCR 057. 存在重复元素 III [Medium] 题解
离散化 + 滑动窗口 + 树状数组。
LCR 057. 存在重复元素 III
给你一个整数数组 nums 和两个整数 k 和
t 。请你判断是否存在两个不同下标 i 和
j,使得:
abs(nums[i] - nums[j]) <= tabs(i - j) <= k
如果存在则返回 true,否则返回 false。
示例 1:
1 | 输入:nums = [1,2,3,1], k = 3, t = 0 |
示例 2:
1 | 输入:nums = [1,0,1,1], k = 1, t = 2 |
示例 3:
1 | 输入:nums = [1,5,9,1,5,9], k = 2, t = 3 |
提示:
0 <= nums.length <= 2 * 10^4- −231 ≤ nums[i] ≤ 231 − 1
0 <= k <= 10^4- 0 ≤ t ≤ 231 − 1
思路
同时满足下标差和数值差两个条件,可以从滑动窗口入手。遍历到下标
i时,只需要在前面的[i-k, i-1]中查找是否存在元素值落在[nums[i]-t, nums[i]+t]内。nums[i]的取值范围很大,而数组长度只有2 * 10^4,所以先将数组排序去重,把每个值离散化为从1开始的排名。用树状数组维护当前窗口内每个离散值出现的次数。
query(x)可以求出排名不超过x的元素数量。bs(v)返回所有离散值中小于等于v的最大排名,因此区间[v-t, v+t]内的元素数量为:query(bs(v+t)) - query(bs(v-t-1))每次查询前先删除已经离开窗口的
nums[i-k-1],查询完再将当前值加入树状数组。这样既能保证下标差不超过k,也不会让当前元素与自己匹配。
代码
1 | import "slices" |
复杂度分析
时间:O(nlog n)。离散化需要排序,每个元素又会进行常数次二分和树状数组操作。
空间:O(n)。离散化数组、映射和树状数组均与输入规模同阶。
Comments
Comment plugin failed to load
Loading comment plugin