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.
区别于上一题,这道不仅有index距离的限制,还加上了两值和的要求。这就要求选择的数据结构能够支持快速的按值搜索。选择TreeSet是因为它内部是用红黑树实现的,所有节点按照natural order从低到高进行排序,可以提供O(logn)的add/remove/contain的操作,并且有floor和ceiling两个method,可用于在一定range进行快速查找。Leetcode上有一个test case测的是Integer值溢出变复数,所以在下面的第二种解法里,用了Long存值,而且要注意int到long类型的cast。
另外一点关于TreeSet需要注意的是,它基于Comparable这个interface进行实现,而Set是基于equals。所以需要考虑compareTo的实现,以保证两者的统一。相关的文档里也作出了强调。
解法一:
1 public static boolean containsNearbyAlmostDuplicate1(int[] nums, int k, int t){ 2 if (k<1 || t<0) return false; 3 4 TreeSet<Integer> set = new TreeSet<Integer>(); 5 for (int i=0;i<nums.length;i++){ 6 int current = nums[i]; 7 if((set.floor(current)!=null && current<= set.floor(current)+t)|| 8 (set.ceiling(current)!=null)&& current>=set.ceiling(current)-t ) 9 return true; 10 set.add(current); 11 12 if(i>=k) 13 set.remove(nums[i-k]); 14 } 15 return false; 16 } 17
解法二:
1 public static boolean containsNearbyAlmostDuplicate2(int[] nums, int k, int t){ 2 if (k<1 || t<0) return false; 3 4 TreeSet<Long> set = new TreeSet<Long>(); 5 for(int i=0;i<nums.length;i++){ 6 int current = nums[i]; 7 SortedSet<Long> subset = set.subSet((long)current-t, (long)current+t+1); 8 9 if(!subset.isEmpty()) return true; 10 set.add((long) current); 11 if(i >=k) set.remove((long)nums[i-k]);//remember to cast it to long 12 } 13 return false; 14 }
Reference:http://www.programcreek.com/2014/06/leetcode-contains-duplicate-iii-java/
时间: 2024-10-18 17:59:35