zoukankan      html  css  js  c++  java
  • 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     }
  • 相关阅读:
    VS2010 自动跳过代码现象
    Reverse Linked List II 【纠结逆序!!!】
    Intersection of Two Linked Lists
    Linked List Cycle II
    Remove Nth Node From End of List 【另一个技巧,指针的指针】
    Swap Nodes in Pairs
    Merge Two Sorted Lists
    Remove Duplicates from Sorted List
    Linked List Cycle
    Dungeon Game
  • 原文地址:https://www.cnblogs.com/skillking/p/9902357.html
Copyright © 2011-2022 走看看