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,j,要求nums[i]和nums[j]的差最多是t,同时i和j的差最多是k
分类:树
解法1:容易想到的思路是维护一个长度为k的窗口,每次检查新值和原窗口中值的差会不会超过t即可。
如果使用两重循环,时间复杂度是O(nk)会超时。我们使用TreeSet去检查差值,使复杂度为O(nLogk)。
SortedSet<E> subSet(E fromElement,E toElement)
set的subSet()方法可以指定一个范围,原来set中在这个范围内的数据,组成一个新的SortedSet返回。
import java.util.SortedSet; public class Solution { public boolean containsNearbyAlmostDuplicate( int [] nums, int k, int t) { if (k< 1 || t< 0 || nums== null || nums.length< 2 ) return false ; SortedSet<Long> set = new TreeSet<Long>(); for ( int j= 0 ; j<nums.length; j++) { SortedSet<Long> subSet = set.subSet((long )nums[j]-t, ( long )nums[j]+t+ 1 ); if (!subSet.isEmpty()) return true ; if (j>=k) { set.remove((long )nums[j-k]); } set.add((long )nums[j]); } return false ; } }
同样的思路,我们可以这样写:
public class Solution { public boolean containsNearbyAlmostDuplicate( final int [] nums, int kk, long t) { if (nums.length < 2 ) return false ; if (kk == 0 ) return false ; TreeSet<Long> window = new TreeSet<Long>(); for ( int i= 0 ;i<nums.length;i++) { if ( window.floor(nums[i] + t) != null && window.floor(nums[i]+t) >= nums[i]-t ) return true ; window.add(new Long(nums[i])); if (i >= kk) { window.remove(new Long(nums[i-kk])); } } return false ; } }
原文链接http://blog.youkuaiyun.com/crazy__chen/article/details/47279997