题目链接:https://leetcode.com/problems/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 difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.
解题思路:
滑动窗口 + TreeSet
这个题自己没有想出来。。。大概能想到数据结构是 Tree,再加上滑动窗口的概念。但是没有很好地把它们整合到一起。
参考LeetCode Discuss:https://leetcode.com/discuss/38177/java-o-n-lg-k-solution TreeSet 数据结构(Java)使用红黑树实现,是平衡二叉树的一种。 该数据结构支持如下操作:
1. floor() 方法返 set 中 ≤ 给定元素的最大元素;如果不存在这样的元素,则返回 null。
2. ceiling() 方法返回 set 中 ≥ 给定元素的最小元素;如果不存在这样的元素,则返回 null。
参考链接:http://bookshadow.com/weblog/2015/06/03/leetcode-contains-duplicate-iii/
public class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if(k < 1 || t < 0)
return false;
TreeSet<Integer> set = new TreeSet<Integer>();
for(int i = 0; i < nums.length; i++){
int n = nums[i];
if(set.floor(n) != null && n <= t + set.floor(n) ||
set.ceiling(n) != null && set.ceiling(n) <= t + n)
return true;
set.add(n);
if (i >= k)
set.remove(nums[i - k]);
}
return false;
}
}
29 / 29 test cases passed.
Status: Accepted
Runtime: 504 ms
还有另一种解法,思路差不多,但更加巧妙的运用了 TreeSet 的方法。
SortedSet subSet(E fromElement, E toElement)
返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。
参考链接:http://www.programcreek.com/2014/06/leetcode-contains-duplicate-iii-java/
import java.util.SortedSet;
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (k < 1 || t < 0)
return false;
SortedSet<Long> set = new TreeSet<Long>();
for (int j = 0; j < nums.length; j++) {
long leftBoundary = (long) nums[j] - t;
long rightBoundary = (long) nums[j] + t + 1;
SortedSet<Long> subSet = set.subSet(leftBoundary, rightBoundary);
if (!subSet.isEmpty())
return true;
set.add((long) nums[j]);
if (j >= k) {
set.remove((long) nums[j - k]);
}
}
return false;
}
29 / 29 test cases passed.
Status: Accepted
Runtime: 524 ms
注意:
一开始提交代码时,显示编译错误 cannot find symbol: class SortedSet。上网找了找原因,发现是需要自己导入包,leetcode 上本身不具有。因此多加了一句 import java.util.SortedSet;