標籤:
題目: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.
思路:相比於I和II,稍微複雜,常規的思路,維護一個長為k的視窗,如果用迴圈判斷會逾時,考慮到問題的特性,用TreeSet中的相關方法來實現:
ceiling(e) : 返回set中大於或等於參數e的最小值,無則返回null;
floor(e) : 返回set中小於或等於參數e的最小值,無則返回null;
在k大小的範圍內進行判斷,每超過一個,從開頭出remove一個值。
代碼:
public class Solution { public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) { TreeSet<Long> set = new TreeSet<Long>(); for(int i = 0 ; i < nums.length ; i++){ if(i-k-1>=0) set.remove((long)nums[i-k-1]); if(set.ceiling((long)nums[i]) != null){//大於等於nums[i]的最小元素 long temp = set.ceiling((long)nums[i]); if(Math.abs(temp - nums[i]) <= t) return true; } if(set.floor((long)nums[i]) != null){//大於等於nums[i]的最小元素 long temp = set.floor((long)nums[i]); if(Math.abs(temp - nums[i]) <= t) return true; } set.add((long)nums[i]); } return false; }}
又在網上看到更簡潔的方法,也是利用TreeSet中的方法:
SortedSet<E> subSet(E fromElement, E toElement)
返回此 set 的部分視圖,其元素從 fromElement(包括)到 toElement(不包括)。
可以直接將兩個判斷化簡在一起(不過LeetCode上沒有過 cannot find symbol: class SortedSet 因此需要自己匯入包,注意上面的import)。
代碼:
import java.util.SortedSet;public class Solution { public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) { if(t<0) return false; TreeSet<Long> set = new TreeSet<Long>(); for(int i = 0 ; i < nums.length ; i++){ if(i-k-1>=0) set.remove((long)nums[i-k-1]); SortedSet<Long> subSet = set.subSet((long)nums[i]-t, (long)nums[i]+t+1); //t為負的話 fromKey > toKey 因此開始要判斷 if(!subSet.isEmpty()) return true; set.add((long)nums[i]); } return false; }}
參考資料:http://blog.csdn.net/thinking2013/article/details/46336373
http://blog.csdn.net/xudli/article/details/46323247
[LeetCode-JAVA] Contains Duplicate III