• 220. 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 absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.

    此题和contains Duplicate的1,2略有不同,在2的基础上添加的一个条件,即定义域为k的范围内的数组,值域为t。

    此题开始没有什么思路,看了大神的解体方法后恍然大悟。

    1. bucket方法,一般来说,给出了定义域和值域的题目都可以用bucket方法来解决。此题就是这种类型。首先,数组里面因为有负数,所以为了统一整个数组的范围全部为正数,有nums[i]-Integer.MIN_VALUE操作。因为数组里面的数全部是整型,不存在小数点的情况,所以每一个bucket的范围内如果要能装下t的值域范围,bucket的范围就应该是t+1,一会将会举例说明。这里要用到hashmap的数据结构,hashmap的key值为bucket值,value值为nums[i]-Integer.MIN_VALUE。那么接下来就有三种情况要考虑。第一种情况,如果hashmap的key值包括新求出的bucket值,那么肯定符合条件了。第二种情况,如果hashmap的key值包括新求出的bucket-1的值,那么就要看nums[i]-Integer.MIN_VALUE与map.get(bucket-1)的差值是否在t的范围内。第三种情况,如果hashmap的key值包括新求出的bucket+1的值,那么就要看nums[i]-Integer.MIN_VALUE与map.get(bucket+1)的差值是否在t的范围内。

    假设数组里面全是正整数,这里不给定义域了,值域为3.注意看bucket=2的情况,bucket-1=1,而8-6=2,也在3的范围里面,所以也符合条件,代码如下:

    public class Solution {

        public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {

            Map<Long,Long> map = new HashMap<Long,Long>();

            if(k<1||t<0) return false;

            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.size()>=k){

                    long lastbucket = ((long)nums[i-k]-Integer.MIN_VALUE)/((long)t+1);

                    map.remove(lastbucket);

                }

                map.put(bucket,remappedNum);

            }

            return false;

        }

    }

    第二种方法用二分搜索树来做,注意treeset的两个方法即floor(返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null)和ceiling(返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null)。代码如下:

    public class Solution {

        public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {

            if(nums==null||k<1||t<0) return false;

            TreeSet<Long> value =new TreeSet<Long>();

            for(int i=0;i<nums.length;i++){

                Long floor = value.floor((long)nums[i]+t);

                Long ceil = value.ceiling((long)nums[i]-t);

                if((floor!=null&&floor>=(long)nums[i])||(ceil!=null&&ceil<=(long)nums[i])){

                    return true;

                }

                value.add((long)nums[i]);

                if(i>=k){

                    value.remove((long)nums[i-k]);

                }

            }

            return false;

        }

    }

  • 相关阅读:
    【oracle】查看表空间对应文件所在位置
    【oracle】查看表空间信息
    【java异常】java.lang.Integer cannot be cast to java.lang.String
    【oracle】DATE输出是什么东西
    数字万用表的精度和分辨率,ADC的位数
    二阶系统
    Verilog中实现电平检测
    模拟信号和数字信号,直流信号和交流信号
    噪声:强度,方差信噪比(待完善)
    Simulink模块之Band-Limited White Noise
  • 原文地址:https://www.cnblogs.com/codeskiller/p/6359733.html
Copyright © 2020-2023  润新知