LeetCode220. 存在重复元素 III

  1. 存在重复元素 III
    给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k 。

如果存在则返回 true,不存在返回 false。

示例 1:

输入:nums = [1,2,3,1], k = 3, t = 0
输出:true

示例 2:

输入:nums = [1,0,1,1], k = 1, t = 2
输出:true

示例 3:

输入:nums = [1,5,9,1,5,9], k = 2, t = 3
输出:false

提示:

0 <= nums.length <= 2 * 104
-231 <= nums[i] <= 231 - 1
0 <= k <= 104
0 <= t <= 231 - 1

注:要用long,因为如果是一个正的int最大减负的int最大就要越界。

class Solution {
  public  boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        Map<Long,Long> map = new HashMap<>();//用来保存当前数及其对应桶的序号
        int n = nums.length;
        for(int i = 0;i<n;i++){
            //获得该数的桶序号
            long id = getId(nums[i],t);


            //i是下标,对于下标i,有效的下标为[i-k,i+k]。但是是遍历的,所以不用考虑[i,i+k]这部分
            // ,如果i-(k+1)就证明前面已经有数已经不满足下标的条件了。要将其的桶删除
            //例如k=3,数组为0,1,2,3,4.当前下标为4,值为4,所以下标为0值为0.有效的下标为:1,2,3,4.d
            //当前下标为0的已经不满足了,因为4-(k+1)>=0 了。
            if( i -(k+1) >=0){
                //删除下标为 i-(k+1)的桶序
                map.remove((long)getId(nums[i-(k+1)],t),(long)nums[i-(k+1)]);
            }

            //如果当前已经包含了该桶序
            if(map.containsKey(id)){
                return true;
            }

            //看前面的邻桶有没有
            if(map.containsKey(id-1) && Math.abs(nums[i] - map.get(id - 1)) <= t){
                return true;
            }

            //看后面的邻桶有没有
            if(map.containsKey(id+1) && Math.abs(nums[i] - map.get(id + 1)) <= t){
                return true;
            }

            map.put((long)getId(nums[i],t),(long) nums[i]);

           

        }
        return  false;
    }
    public static int getId(int x,int t){
        //如果x元素大于等于零,直接分桶
        if(x>=0){
            return x / ( t + 1 );
        }else{
            //如果x元素小于零,偏移后再分桶
            return ( x + 1 )/( t + 1 ) - 1 ;
        }
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超好的小白

没体验过打赏,能让我体验一次吗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值