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

Subscribe to see which companies asked this question.

最直接的方式是对数组前nums.length-k个元素进行与其前面t个元素值进行比较的方式进行计算,如果找到则直接返回true结束运算,否则,计算结束后返回false表示未找到。

public class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        if(nums==null || nums.length==1)
            return false;
        if(k > nums.length) k=nums.length;
        for(int i=0;i<nums.length-k;i++) {
            for(int j=1;(j<=k) && (i+j < nums.length);j++) {
                if(Math.abs(nums[i]-nums[i+j])<=t)
                    return true;
            }
        }
        return false;
    }
}
但是看到解答里的采用TreeSet的方式觉得比较巧妙,用到了TreeSet的floor()、ceil()两个方法,分别含义是:

floor(value)表示在这个TreeSet里小于等于value的最大值,

ceil(value)表示大于等于value的最小值。若存在则返回值,否则返回null

下面的例子展示java.util.TreeSet.floor()方法的使用。

TreeSet <Integer>treeadd = new TreeSet<Integer>();
	     // adding in the tree set
	     treeadd.add(12);
	     treeadd.add(11);
	     treeadd.add(16);
	     treeadd.add(15);
	     // getting floor and ceiling value for 12
	     System.out.println("\nfloor value for 12: "+treeadd.floor(12)); 
	     System.out.println("Ceiling value for 12: "+treeadd.ceiling(12)); 
	     // getting floor and ceiling value for 13
	     System.out.println("\nfloor value for 13: "+treeadd.floor(13)); 
	     System.out.println("Ceiling value for 13: "+treeadd.ceiling(13)); 
	     System.out.println("Ceiling value for 20: "+treeadd.ceiling(20));

现在编译和运行上面的代码示例,将产生以下结果。

floor value for 12: 12
Ceiling value for 12: 12


floor value for 13: 12
Ceiling value for 13: 15
Ceiling value for 20: null
参照答案编写的程序如下:

This problem requires to maintain a window of size k of the previous values that can be queried for value ranges. The best data structure to do that is Binary Search Tree. As a result maintaining the tree of size k will result in time complexity O(N lg K). In order to check if there exists any value of range abs(nums[i] - nums[j]) to simple queries can be executed both of time complexity O(lg K)

Here is the whole solution using TreeMap.

public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        if(nums==null || nums.length==1 || k<=0)
            return false;
        TreeSet<Integer> treeSet = new TreeSet<>();
        for(int i=0;i<nums.length;i++) {
            Integer floor = treeSet.floor(nums[i]+t);
            Integer ceil = treeSet.ceiling(nums[i]-t);
            if((floor!=null && floor>=nums[i]) || (ceil!=null && ceil<=nums[i]))
                return true;
            treeSet.add(nums[i]);
            if(i>=k) {
                treeSet.remove(nums[i-k]);
            }
        }
        return false;
    }
但是运行时,提示

Submission Result: Wrong Answer More Details 
Input: [-2147483648,-2147483647]33
Output: false
Expected: true
原因是,在加减t时可能使得元素超出整数的表达范围,从而使得数值溢出,这个测试用例可能是最近才加入的,所以官方的Solutions里还没有将该答案下架。

但是该种解决问题的思路仍然值得学习和掌握。

还有一种解决思路:

As a followup question, it naturally also requires maintaining a window of size k. When t == 0, it reduces to the previous question so we just reuse the solution.

Since there is now a constraint on the range of the values of the elements to be considered duplicates, it reminds us of doing a range check which is implemented in tree data structure and would take O(LogN) if a balanced tree structure is used, or doing a bucket check which is constant time. We shall just discuss the idea using bucket here.

Bucketing means we map a range of values to the a bucket. For example, if the bucket size is 3, we consider 0, 1, 2 all map to the same bucket. However, if t == 3, (0, 3) is a considered duplicates but does not map to the same bucket. This is fine since we are checking the buckets immediately before and after as well. So, as a rule of thumb, just make sure the size of the bucket is reasonable such that elements having the same bucket is immediately considered duplicates or duplicates must lie within adjacent buckets. So this actually gives us a range of possible bucket size, i.e. t and t + 1. We just choose it to be t and a bucket mapping to be num / t.

Another complication is that negative ints are allowed. A simple num / t just shrinks everything towards 0. Therefore, we can just reposition every element to start from Integer.MIN_VALUE.

 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;
    }
}

Edits:

Actually, we can use t + 1 as the bucket size to get rid of the case when t == 0. It simplifies the code. The above code is therefore the updated version.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误提示表示您的项目构建路径中存在重复的文件或目录。通常,这会导致构建过程中出现错误或意外行为。 要解决此问题,您可以尝试执行以下步骤之一: 1. 清理项目:如果您使用的是IDE(如Eclipse或IntelliJ IDEA),则可以尝试执行“Clean”或“Rebuild”操作,以清理项目并重新生成构建路径。 2. 删除重复的文件或目录:检查您的构建路径,查找重复的文件或目录,并将其删除。 3. 检查依赖项:如果您的项目依赖于其他库或框架,则可能存在冲突或重复的依赖项。尝试检查您的依赖关系,并删除任何重复的依赖项。 希望这些提示对您有帮助! ### 回答2: "build path contains duplicate" 是一个错误提示信息,意思是构建路径中存在重复的内容。通常这个错误会发生在使用开发工具来构建项目时。 造成这个错误的原因可能有很多,比如项目中引用了重复的库文件、重复的资源文件等。解决这个问题可以采取以下步骤: 1. 检查项目的构建路径:打开项目的构建路径设置,检查是否有重复的库文件或资源文件路径。如果有,删除重复的路径。 2. 检查依赖关系:检查项目中的依赖关系,确保每个库文件只被引用一次。 3. 清理和重建项目:清除项目的构建缓存,然后重新构建项目,这样可以使得构建工具重新生成构建路径,解决重复的问题。 4. 更新工具或插件:如果使用的是开发工具或插件,可能是其版本过旧或存在Bug导致的问题。尝试更新工具或插件到最新版本,然后重建项目。 5. 检查项目配置:检查项目的配置文件,例如项目的构建脚本或配置文件,确保没有重复的内容。 总的来说,解决"build path contains duplicate"的问题需要仔细检查项目的构建路径、依赖关系和配置文件等,确保没有重复的内容存在。如果以上方法都无效,可以尝试重建项目或者咨询相关的开发工具提供商,寻求更进一步的帮助。 ### 回答3: "build path contains duplicate"是一个常见的错误消息,它在我们创建、构建或运行项目时可能会出现。这个错误消息意味着我们的构建路径中存在重复的文件或库。 通常,这种错误是由于我们在项目的构建路径里多次引用了相同的文件或库所致。这可能是因为我们在项目配置中添加了多个相同的库,或者多次导入了相同的文件。 要解决这个问题,我们需要检查项目的构建路径并找出重复的部分。首先,我们可以检查项目的构建脚本(如build.gradle或pom.xml)中是否存在多次引用相同的依赖库。如果是这种情况,我们可以删除其中一个重复的引用。 其次,我们还可以检查项目的源代码目录和资源目录,看是否有重复的文件被多次引入。如果是这种情况,我们可以手动删除重复的文件或者调整项目结构,以确保每个文件只被引用一次。 最后,我们还可以检查项目的IDE配置,并查看是否有重复的构建路径配置。有时候IDE工具可能会自动添加一些构建路径,而这些路径与我们手动添加的路径重复了。在这种情况下,我们可以删除重复的构建路径配置。 总之,当我们遇到"build path contains duplicate"错误时,我们需要仔细检查项目的构建路径,找出并删除重复的文件或库。这样,我们就可以成功构建和运行我们的项目了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值