Leetcode题库-存在重复元素3(java语言版)
2019-03-28 00:30
405 查看
题目描述:
给定一个整数数组,判断数组中是否有两个不同的索引 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
这道题和上一道题特别相似,只是将两个元素相同变成了两个元素差的绝对值小于的与一个数(范围就变成了num[i]-t---num[i]+t)。这样的话就有问题,就要考虑不能int越界,所以进行操作时转化为long就可以。(因为abs函数在int越界时会失去作用)
具体思路还是滑动窗口和查找表。滑动窗口的长度是查找表的长度,不能大于k,大于k就将查找表最左边的元素删去,然后在进行比较。比较两个数的绝对值的时,滑动窗口中额所有元素与当前的元素进行计算比较,然后得出结果。
这道题也可以用暴力for,不过还是不推荐,虽然简单,但是时间复杂度高,很容易超时。
代码如下:
[code] int a [] = new int[]{-1,2147483647}; int k =1; int t =2147483647; // 第一种方法,暴力for(考点就是Integer.MAX_VALUE 和Integer.MIN_VALUE 的临界点,所以用abs取绝对值的时候,-2147483648的绝对值还是-2147483648) // for (int i=0;i<a.length;i++){ // for (int j = i+1;j<a.length;j++){ // if (Math.abs ( (long) a[i]-(long) a[j] )<=t &&Math.abs ( (long) i-(long) j )<=k){ // System.out.println(i+" "+j); // System.out.println("true"); // } // } // } // System.out.println("false"); // 第二种方法:滑动窗口加查找:维持滑动窗的大小最大为 k,遍历每一个元素 nums[i],在活动窗口中寻找 |one-nums[i]| <= t,即窗口中的元素范围为:[one-t … one+t] 之间。 // map和set都可以,本题推荐用set,因为要求不是两个元素相等。 // Set<Integer> set = new HashSet ( ); // for (int i =0;i<a.length;i++){ // if ((long)t==0){ //// 判断是否存在重复的元素,存在时并且set长度未大于k返回true。 // if (set.contains ( a[i] )){ // System.out.println("true"); // } // }else { // for (int num:set){ //// 判断是否小于等于t。 // if (Math.abs ((long)num-(long)a[i])<=t){ // System.out.println("true"); // } // } // } // set.add ( a[i] ); // if (set.size ()>k){ // set.remove ( a[i-k] );//删除滑动窗口最左端的元素 // } // } // System.out.println("false");. Map<Integer,Integer> map = new HashMap ( ); for (int i=0;i<a.length;i++){ // 当t=0时,证明两个元素相等,集合中存在这个元素,且未超过k,则证明存在 if ((long)t==0){ if (map.containsKey ( a[i] )){ System.out.println("true"); } }else { //判断滑动窗口内的元素减去数组元素是否小于等于t,(遍历hash判断绝对值是否小于t) for (int key:map.keySet ()) { if (Math.abs ( (long) key - (long) a[i] ) <= t) { System.out.println ( "true" ); } } } // 添加元素 map.put ( a[i],i ); if (map.size ()>k){//滑动窗口的大小不小于k,若大于k是,就将最左边的元素删除。 map.remove ( a[i-k] ); } } System.out.println("false");
查找表用set,用map都是可以的。我两种都写了,可以参考一下。
执行结果:
执行用时:
总结:这道题和上一道题都用到了查找表的相关技术,还有滑动窗口的知识,选择合适的查找表和滑动窗口技巧,可以让我们事半功倍。这三道题特别值得细细品味。
2019-3-28
相关文章推荐
- leetcode 287. Find the Duplicate Number 数组重复元素查询 + 环的存在判定 + 快慢指针 + 很妙的想法
- 存在重复元素 - LeetCode
- 【LeetCode-面试算法经典-Java实现】【219-Contains Duplicate II(包含重复元素II)】
- LeetCode217.python实现: 存在重复元素问题☆
- [leetcode]存在重复元素[javascript]
- leetcode217. 存在重复元素
- 存在重复元素 II - LeetCode
- [leetcode]存在重复元素 II[javascript]
- [Leetcode] 82. 删除排序链表中的重复元素 II java
- leetcode:java.T018_4Sum---给定一个整数数组,找出a + b + c + d = target的唯一解,不能有重复元素组
- 【LeetCode】Python实现-217. 存在重复元素
- leetcode 220. 存在重复元素 III
- 【LeetCode】Python实现-219. 存在重复元素 II
- 【LeetCode-面试算法经典-Java实现】【082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)】
- leetcode219. 存在重复元素 II
- (Java) LeetCode 83. Remove Duplicates from Sorted List —— 删除排序链表中的重复元素
- (Java) LeetCode 82. Remove Duplicates from Sorted List II —— 删除排序链表中的重复元素 II
- leetcode-java.T015_3Sum---给定一个n个元素的数组,是否存在a,b,c三个元素,使用得a+b+c=0,找出所有符合这个条件的三元组
- [Leetcode] 83. 删除排序链表中的重复元素 java
- leetcode 217.存在重复元素