力扣220(java)-存在重复元素 III(困难)
题目:
给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 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=2147483647
- 0 <= k <= 104
- 0 <= t <= 231 - 1
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/contains-duplicate-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
题解参考@【liweiwei1419】
滑动窗口&红黑树(TreeSet):
题目中的两个要求: 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t,同时又满足abs(i - j) <= k。
1.对于两个位置的下标的范围,可以维护一个长度为 k + 1的滑动窗口(解释:[1,3,5,3,4,6] k =3,滑动窗口的长度可以为4,因为在四个连续的数的下标差一定会小于等于3)。但是滑动窗口中的元素可能为k个,也可能为k+1个,如果先插入新元素则是k+1个,如果是先删除最左端的元素,则是k个。
2.对于两个位置所对应的数字差范围:abs(nums[i] - nums[j]) <= t,可以转换为:-t <= nums[i] - nums[j] <= t,把nums[i]看做新遍历到的元素,nums[j]看做是在滑动窗口里面的元素,将上述不等式可以转换为:
- 条件1:nums[j] >= nums[i] - t;
- 条件2:nums[j] <= nums[i] + t;
条件2的nums[i] + t的值固定,为了让条件2有更多的值成立,条件1找到得到nums[j]需要尽可能的小才行,于是就等价于找大于等于nums[i] - t的最小值,等价于找到nums[i] - t的最小上界。java中的ceiling(key)函数提供了这样的功能:返回大于等于key的最小元素,如果不存在,返回空。
【为什么使用二分搜索树】解释来自【作者:liweiwei1419】
理由 1:由于维护的是固定长度的一系列数,除了最开始的几个数添加进数据结构以外。
当程序看到下标为 k + 1的元素的时候,就需要移除下标为 00 的元素;
当程序看到下标为 k + 2的元素的时候,就需要移除下标为 11 的元素。
频繁的删除和添加元素,符合条件的数据结构是「查找表」,「查找表」的两种实现分别是「哈希表」和「二分搜索树(红黑树)」。
理由 2:根据上面的分析,我们需要找到 nums[i] - t 的最小上界,「哈希表」是不维护元素顺序性的,而「二分搜索树」恰好维护了顺序性,是当前场景下合适的数据结构。且哈希表无法很好的支持范围查询。
注意:
int的溢出问题:例如nums= [-2147483640, -2147483641],k = 1, t = 100,nums[i] - t = -21474836740就会超过int 的最小值范围,故用long 类型来存储。
java代码:
1 class Solution {
2 public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
3 TreeSet<Long> set = new TreeSet<>();
4 for(int i = 0; i < nums.length; i++){
5 //查找大于等于nums[i]-t的最小值
6 Long ceiling = set.ceiling((long)nums[i] - (long)valueDiff);
7 if(ceiling != null && ceiling <= ((long)nums[i] + (long)valueDiff)){
8 return true;
9 }
10 set.add((long)nums[i]);
11 //限制滑动窗口的大小
12 if(set.size() == indexDiff + 1){
13 set.remove((long)nums[i - indexDiff]);
14 }
15 }
16 return false;
17 }
18 }

小知识:
1.java集合中存在以下两种方法:
floor(E e) 方法返回在这个集合中小于或者等于给定元素的最大元素,如果不存在这样的元素,返回null。
ceiling(E e) 方法返回在这个集合中大于或者等于给定元素的最小元素,如果不存在这样的元素,返回null。
2.TreeSet 是一个有序集合,它的作用是提供有序的Set集合。其继承于 AbstractSet 类TreeSet 实现了 NavigableSet 接口,意味着它支持一系列的导航方法。比如查找指定目标最匹配项。
TreeSet 是通过 TreeMap 实现的一个有序的、不可重复的集合,底层维护的是红黑树结构。当TreeSet的泛型对象不是java的基本类型的包装类时,对象需要实现接口Comparable并重写此接口中的compareTo()方法。 TreeSet 实现了 Serializable 接口,所以它支持序列化。
力扣220(java)-存在重复元素 III(困难)的更多相关文章
- Java实现 LeetCode 220 存在重复元素 III(三)
220. 存在重复元素 III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最 ...
- Leetcode 220.存在重复元素III
存在重复元素III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. ...
- 【每日算法】存在重复元素 III
题目描述 这是 LeetCode 上的 220. 存在重复元素 III, 难度为 [中等] 给你一个整数数组 nums 和两个整数 k 和 t .请你判断是否存在 两个不同下标 i 和 j,使得 ab ...
- [LeetCode] 220. Contains Duplicate III 包含重复元素 III
Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...
- 力扣——remove element(删除元素) python实现
题目描述: 中文: 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) ...
- 力扣题目汇总(重复N次元素,反转字符串,斐波那契数)
重复 N 次的元素 1.题目描述 在大小为 2N 的数组 A 中有 N+1 个不同的元素,其中有一个元素重复了 N 次. 返回重复了 N 次的那个元素. 示例 1: 输入:[1,2,3,3] 输出:3 ...
- [LeetCode]220. 存在重复元素 III
题目链接:https://leetcode-cn.com/problems/contains-duplicate-iii/ 题目描述: 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使 ...
- 220. 存在重复元素 III
题目: 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. 示例 1: ...
- 力扣Leetcode 3. 无重复字符的最长子串
无重复字符的最长子串 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串 ...
- [Swift]LeetCode220. 存在重复元素 III | Contains Duplicate III
Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...
随机推荐
- docker部署文件
- Base MYSQL Database create stored procedures resolve the Delimiter error
Base MYSQL Database create stored procedures resolve the Delimiter error, It must be created using a ...
- 【剑指 Offer II 118. 多余的边】并查集求回路
class Solution { int[] parent; int[] rank; public void init(int n) { parent = new int[n + 1]; rank = ...
- 3DCAT首届行业生态交流会|燧光CTO 戴景文:云渲染 XR大发展的助推器
2021年12月17日下午,由深圳市瑞云科技有限公司主办,深圳市虚拟现实产业联合会协办的 云XR如何赋能元宇宙--3DCAT实时云渲染首届行业生态合作交流会 圆满落幕.此次活动围绕"云XR如 ...
- .NET周刊【3月第2期 2024-03-17】
国内文章 开源.NET8.0小项目伪微服务框架(分布式.EFCore.Redis.RabbitMQ.Mysql等) https://www.cnblogs.com/aehyok/p/18058032 ...
- 自定义Key类型的字典无法序列化的N种解决方案
当我们使用System.Text.Json.JsonSerializer对一个字典对象进行序列化的时候,默认情况下字典的Key不能是一个自定义的类型,本文介绍几种解决方案. 一.问题重现 二.自定义J ...
- 2024-03-23:用go语言,一张桌子上总共有 n 个硬币 栈 。每个栈有 正整数 个带面值的硬币, 每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里。
2024-03-23:用go语言,一张桌子上总共有 n 个硬币 栈 .每个栈有 正整数 个带面值的硬币, 每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里. ...
- drools中使用全局变量
一.背景 在我们编写drools的规则文件的时候,有些时候需要用到全局变量,那么这个该怎么实现呢?有哪些注意事项呢? 二.前置知识 1.语法结构 2.全局变量的特点 使用global来定义全局变量,它 ...
- 从零开始写 Docker(九)---实现 mydocker ps 查看运行中的容器
本文为从零开始写 Docker 系列第九篇,实现类似 docker ps 的功能,使得我们能够查询到后台运行中的所有容器. 完整代码见:https://github.com/lixd/mydocker ...
- C# 消息发送
界面 frmMain using System; using System.Collections.Generic; using System.ComponentModel; using System ...