zoukankan      html  css  js  c++  java
  • 0220. Contains Duplicate III (M)

    Contains Duplicate III (M)

    题目

    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
    

    题意

    判断数组中是否存在这样一组数,它们的值之差的绝对值不大于t,且下标之差的绝对值不大于k。

    思路

    最简单的方法是直接遍历,再判断当前数与它之后的k个数的差值是否符合条件。

    优化的方法是借助红黑树实现滑动窗口思想:在红黑树中只保存k+1个连续的数(这样就控制了树中所有数的下标差不大于k),每次加入新数时,先去除一个数(容量已到达k+1的情况下),在树中找到小于新数的最大数和大于新数的最小数,判断它们与新数的差是否满足条件,最后将新数加入红黑树中。


    代码实现

    Java

    暴力法

    class Solution {
        public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
            if (t < 0) {
                return false;
            }
            
            for (int i = 0; i < nums.length; i++) {
                for (int j = i + 1; j <= Math.min(i + k, nums.length - 1); j++) {
                  	// 不转化为long可能会有溢出
                    if (Math.abs((long) nums[i] - (long) nums[j]) <= (long) t) {
                        return true;
                    }
                }
            }
          
            return false;
        }
    }
    

    红黑树

    class Solution {
        public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
            if (t < 0) {
                return false;
            }
          
            TreeSet<Integer> set = new TreeSet<>();
            for (int i = 0; i < nums.length; i++) {
              	// 保证树的容量始终不超过k+1
                if (i > k) {
                    set.remove(nums[i - k - 1]);
                }
                if (set.contains(nums[i])) {
                    return true;
                }
              	// 因为可能为null,所以必须用包装类接收
                Integer lower = set.lower(nums[i]);
                Integer higher = set.higher(nums[i]);
              	// 转换成long计算防止溢出
                if (lower != null && (long) nums[i] - lower <= t
                        || higher != null && (long) higher - nums[i] <= t) {
                    return true;
                }
                set.add(nums[i]);
            }
          
            return false;
        }
    }
    

    JavaScript

    暴力法

    /**
     * @param {number[]} nums
     * @param {number} k
     * @param {number} t
     * @return {boolean}
     */
    var containsNearbyAlmostDuplicate = function (nums, k, t) {
      for (let i = 0; i < nums.length; i++) {
        for (let j = i + 1; j <= i + k && j < nums.length; j++) {
          if (Math.abs(nums[j] - nums[i]) <= t) {
            return true
          }
        }
      }
      return false
    }
    

    参考
    very simple and clean solution on Java (72.47%)

  • 相关阅读:
    MSSQL 2012 密钥
    同台同时多开DELPHI2007的解决办法
    DELPHI快捷键
    Delphi编码规范
    解决Delphi 2010启动时卡死并报“displayNotification: 堆栈溢出”错误
    Test
    sched python 定时任务
    springboot2.x 整合redis
    springboot 忽略null属性值,不传递
    logback.xml 配置使用
  • 原文地址:https://www.cnblogs.com/mapoos/p/13605022.html
Copyright © 2011-2022 走看看