zoukankan      html  css  js  c++  java
  • LeetCode 220. Contains Duplicate III

    原题链接在这里:https://leetcode.com/problems/contains-duplicate-iii/

    题目:

    Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.

    题解:

    借助于TreeSet的subSet函数,看是否有[nums[i]-t, nums[i]+t]范围内的数。

    同时维护一个长度为k的窗口,超过了这个长度时就把前面的元素从window中拿出去。

    若在window长度范围内,就把nums[i]加进window中。

    Note: 

    当i>=k, 也就是TreeSet.size()>=k时, 就把这个nums[i-k]从window中拿出去.

    这里要先把旧的拿出去才能加新的,因为若是这个要加的新的恰好等于旧的,就会覆盖掉原来的,再拿掉时就会错拿新的。

    Time Complexity is O(nlogk). window 的长度为k, TreeSet的contains, insert, delete用时都是O(log k).

    Space O(k).

    AC Java:

     1 public class Solution {
     2     public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
     3         if(nums == null || nums.length < 2 || k < 1 || t<0){
     4             return false;
     5         }
     6         TreeSet<Long> window = new TreeSet<Long>();
     7         for(int i = 0; i<nums.length; i++){
     8             SortedSet<Long> set = window.subSet((long)nums[i]-t, true, (long)nums[i]+t, true);
     9             if(!set.isEmpty()){
    10                 return true;
    11             }else{
    12                 if(i>=k){
    13                     window.remove((long)nums[i-k]);
    14                 }
    15                 window.add((long)nums[i]);
    16             }
    17         }
    18         return false;
    19     }
    20 }

    也可采用Bucket. e.g. t=2, 就把(0,1,2)放在一个bucket, (3,4,5)放在下一个bucket等等.

    当新的num mapped 到的bucket已经有数, 则return true. 并且检查上下各一个bucket. 上面的例子3-2=1也是小于t的.

    这里负数也是允许的, -2/3 = 0, 2/3 = 0. -2 和 2 会map到一个bucket下面. 但2-(-2) = 4已经大于t了. 所以map时num都从Integer.MIN_VALUE开始计数.

    另为了避免t=0的情况,求bucketNum时,除以(t+1).

    Time Complexity: O(nums.length). Space: O(k).

    AC Java:

     1 public class Solution {
     2     public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
     3         if(nums == null || nums.length < 2 || k < 1 || t < 0){
     4             return false;
     5         }
     6         
     7         HashMap<Long, Long> hm = new HashMap<Long, Long>();
     8         for(int i = 0; i<nums.length; i++){
     9             long mappedNum  = (long)nums[i] - Integer.MIN_VALUE;
    10             long bucketNum = mappedNum/((long)t+1);
    11             if(hm.containsKey(bucketNum)
    12                 ||(hm.containsKey(bucketNum-1) && mappedNum-hm.get(bucketNum-1)<=t)
    13                 ||(hm.containsKey(bucketNum+1) && hm.get(bucketNum+1)-mappedNum<=t)){
    14                     return true;
    15             }else{
    16                 if(i >= k){
    17                     long lastBucketNum = ((long)nums[i-k]-Integer.MIN_VALUE)/((long)t+1);
    18                     hm.remove(lastBucketNum);
    19                 }
    20                 hm.put(bucketNum, mappedNum);
    21             }
    22         }
    23         return false;
    24     }
    25 }

    类似Contains Duplicate II.

  • 相关阅读:
    模板模式创建一个poi导出功能
    vim python和golang开发环境配置
    vim快捷键
    golang聊天室
    goroutine与channels
    Redis中的GETBIT和SETBIT(转载)
    二叉树
    满二叉树与完全二叉树
    拓扑排序
    ZigZag Conversion
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/4924607.html
Copyright © 2011-2022 走看看