码迷,mamicode.com
首页 > 其他好文 > 详细

220. Contains Duplicate III

时间:2020-06-25 12:23:09      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:ORC   turn   意思   i++   负数   桶排序   NPU   pre   force   

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

Example 1:

Input: nums = [1,2,3,1], k = 3, t = 0
Output: true

Example 2:

Input: nums = [1,0,1,1], k = 1, t = 2
Output: true

Example 3:

Input: nums = [1,5,9,1,5,9], k = 2, t = 3
Output: false

1. brute force
注意里面有用到long,因为可能会有边界条件:
[-1,2147483647]
1
2147483647
而 2147483647 + 1 = -2147483648
class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        Map<Integer, HashSet<Integer>> map = new HashMap();
        int le = nums.length;
        for(int i = 0; i < le; i++){
            for(int j = i + 1; j < le; j++){
                long abs = Math.abs((long)nums[j] - (long)nums[i]);
                if(abs <= t){
                    if(j - i <= k){
                        System.out.println(abs);
                        return true;
                    }                    
                }                
            }
        }
        return false;
    }
}

2. 桶排序,具体看讲解

 public class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        if (k < 1 || t < 0) return false;
        Map<Long, Long> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            long remappedNum = (long) nums[i] - Integer.MIN_VALUE;
            long bucket = remappedNum / ((long) t + 1);
            if (map.containsKey(bucket)
                    || (map.containsKey(bucket - 1) && remappedNum - map.get(bucket - 1) <= t)
                        || (map.containsKey(bucket + 1) && map.get(bucket + 1) - remappedNum <= t))
                            return true;
            if (map.entrySet().size() >= k) {
                long lastBucket = ((long) nums[i - k] - Integer.MIN_VALUE) / ((long) t + 1);
                map.remove(lastBucket);
            }
            map.put(bucket, remappedNum);
        }
        return false;
    }
}

大概意思是因为两数最大差是t,就把桶的容量设为t+1,例如[0,1,2,3,4], t = 2,桶0【0,1,2】,桶1【3,4】,而且可以避免t==0的以t为桶容量时候除以0

最开始要remap所有的数,避免负数情况以及Integer.MAX_VALUE == 2^31 - 1的情况,很狗,所以下面所有的数都变成long.

如果两数在一个桶里(通过map.containsKey()实现,说明两数之差小于t),但也要注意相邻桶的状况,比如2和3也只差1<t==2, 说明我们也要判断一下左边右边桶里的数。!!!看到这才发现,每只桶里一直最多只有1个元素(这样才能比较)

--》最后是if (map.entrySet().size() >= k) ,这个是因为两个index不能超过k,那为啥这么实现?因为我们index是i,从0到k-1一直相安无事,直到i > =k,就像一个window.然后因为我们是先判断后put,最终会维持map size为k

很巧妙的方法,但也用了很多时间读懂,还要提高

220. Contains Duplicate III

标签:ORC   turn   意思   i++   负数   桶排序   NPU   pre   force   

原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13191133.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!