• 220. Contains Duplicate III


    一、题目

      1、审题

      

      2、分析

        判断数组中是否存在两个元素之差在 t 之内,且此两个元素下标之差在 k 之内。

    二、解答

      1、思路:

        方法一、

          桶排序

        ①、采用 Map ,key 记录桶的序号,value 记录元素的值。每个桶的元素个数为 t + 1, eg t=3,则桶大小为 4, 元素 0、1、2、3 在一个桶,桶元素最大差值为 3 - 0 = 3 <= t 。

        ②、由于存在 (t + 1, -t -1) 都存在于桶序号为 0 的同一个桶,为了消除这个错误,将元素化为 Long,且值均大于 0。做法是 key 用  nums[i] - Integer.MIN_VALUE 表示。

        ③、若遍历的连续的 k 个元素中出现在同一个桶情况,则返回 true,若有连续桶,则比较这两个元素值。

        ④、当桶数大于 k 了,则去除最早添加的一个桶,添加新的遍历的元素的 entry。

     1     public boolean containsNearbyAlmostDuplicate2(int[] nums, int k, int t) {
     2         
     3         if(k < 1 || t < 0)
     4             return false;
     5         
     6         HashMap<Long, Long> map = new HashMap<>();
     7         for (int i = 0; i < nums.length; i++) {
     8             // Integer 范围是 [-2147483648, 2147483647]
     9             // nums[i] - Integer.MIN_VALUE 使得所有数值均  >= 0, 否则  (t+1, -t-1) 均在 0 这个桶内  
    10             long remappendNum = (long) nums[i] - Integer.MIN_VALUE;
    11             long bucket = remappendNum / ((long)t + 1);
    12             if(map.containsKey(bucket)
    13                 ||    (map.containsKey(bucket - 1) && remappendNum - map.get(bucket - 1) <= t)
    14                     || (map.containsKey(bucket + 1) && map.get(bucket + 1) - remappendNum <= t))
    15                     return true;
    16             
    17             if(map.entrySet().size() >= k) {
    18                 long lastBucket = ((long) nums[i - k] - Integer.MIN_VALUE) / ((long)t + 1);
    19                 map.remove(lastBucket);
    20             }
    21             map.put(bucket, remappendNum);
    22         }
    23         return false;
    24     }

      方法二、

        采用 TreeSet

        注意将 Integer 转为 Long 型进行比较,避免溢出情况。

     1 // TreeSet 继承自 NavigableSet,NavigableSet 提供导航方法:
     2     /*
     3      *  1、 lower(e): 返回 小于 给定值的元素
     4      *  2、floor(e): 小于等于
     5      *  3、ceiling(e): 大于等于
     6      *  4、higher(e): 大于
     7      */
     8     public boolean containsNearbyAlmostDuplicate3(int[] nums, int k, int t) {
     9         
    10         if(k < 1 || t < 0)
    11             return false;
    12         
    13         TreeSet<Long> values = new TreeSet<>();
    14         for (int i = 0; i < nums.length; i++) {
    15             long num = nums[i];    // 转为 Long 型,避免了整形溢出情况。
    16             Long floor = values.floor(num + t); // 小于等于
    17             Long ceil = values.ceiling(num - t); // 大于等于
    18             if((floor != null && floor >= num)
    19                     || (ceil != null && ceil <= num))
    20                 return true;
    21             
    22             values.add(num);
    23             if(i >= k)
    24                 values.remove((long)(nums[i - k]));
    25         }
    26         return false;
    27     }
  • 相关阅读:
    mysql脚本导入导出
    centos6.9关闭防火墙
    hdfs 架构
    MySQL JOIN的使用
    六种方式,教你在SpringBoot初始化时搞点事情!
    mybatis快速入门
    有了Swagger2,再也不用为写Api文档头疼了
    kafka查看Topic列表及消费状态等常用命令
    @RequestMapping注解
    寻找写代码感觉(三)之使用 Spring Boot 编写接口
  • 原文地址:https://www.cnblogs.com/skillking/p/9902357.html
Copyright © 2020-2023  润新知