您的位置:首页 > 编程语言 > Java开发

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: