题目描述:
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.
这个题和前面的2个没有什么关系。
滑动窗口+treeset做法:
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || nums.length == 0 || k <= 0) {
return false;
}
final TreeSet<Integer> values = new TreeSet<>();
for (int ind = 0; ind < nums.length; ind++) {
final Integer floor = values.floor(nums[ind] + t);
final Integer ceil = values.ceiling(nums[ind] - t);
if ((floor != null && floor >= nums[ind])
|| (ceil != null && ceil <= nums[ind])) {
return true;
}
values.add(nums[ind]);
if (ind >= k) {
values.remove(nums[ind - k]);
}
}
return false;
}
二叉搜索树做法,其实和上面的思想一样,但是这个写起来太麻烦~~~
public class Solution {
class TreeNode{
long val;
TreeNode left;
TreeNode right;
public TreeNode(long x) {
val = x;
}
}
private TreeNode add(TreeNode root, TreeNode nNode) {
if(root == null) {
return nNode;
}
else if(root.val < nNode.val) {
root.right = add(root.right, nNode);
return root;
}
else {
root.left = add(root.left, nNode);
return root;
}
}
private TreeNode delete(TreeNode root, TreeNode dNode) {
if(root == null) {
return null;
}
else if(root.val < dNode.val) {
root.right = delete(root.right, dNode);
return root;
}
else if(root.val > dNode.val) {
root.left = delete(root.left, dNode);
return root;
}
else if(root == dNode) {
if(dNode.left == null && dNode.right == null) return null;
else if(dNode.left != null && dNode.right == null) return dNode.left;
else if(dNode.right != null && dNode.left == null) return dNode.right;
else {
TreeNode p = dNode.right;
while(p.left != null) p = p.left;
dNode.right = delete(dNode.right, p);
p.left = dNode.left;
p.right = dNode.right;
return p;
}
}
else {
return root;
}
}
private boolean search(TreeNode root, long val, int t) {
if(root == null) {
return false;
}
else if(Math.abs((root.val - val)) <= t) {
return true;
}
else if((root.val - val) > t) {
return search(root.left, val, t);
}
else {
return search(root.right, val, t);
}
}
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if(k < 1 || t < 0 || nums.length <= 1) {
return false;
}
int len = nums.length;
TreeNode[] map = new TreeNode[len];
map[0] = new TreeNode((long)nums[0]);
TreeNode root = null;
root = add(root, map[0]);
for(int i = 1; i < len; i++) {
if(search(root, (long)nums[i], t)) {
return true;
}
map[i] = new TreeNode((long)nums[i]);
if(i - k >= 0) {
root = delete(root, map[i-k]);
}
root = add(root, map[i]);
}
return false;
}
}
下面这个方法也很巧妙:!!!将value和index存储起来,然后排序
class Pair {
int val;
int index;
Pair(int v, int i) {
this.val = v;
this.index = i;
}
@Override
public String toString() {
return "Pair [val=" + val + ", index=" + index + "]";
}
}
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || nums.length < 2 || t < 0 || k < 1) {
return false;
}
int len = nums.length;
Pair[] pair = new Pair[len];
for(int i = 0; i < len; i++) {
pair[i] = new Pair(nums[i], i);
}
Arrays.sort(pair, new Comparator<Pair> () {
public int compare(Pair p1, Pair p2) {
return p1.val - p2.val;
}
});
for (int i = 0; i < pair.length; i++) {
System.out.println(pair[i]);
}
for(int i = 0; i < len; i++) {
for(int j = i + 1; j < len && Math.abs((long)pair[j].val - (long)pair[i].val) <= (long)t; j++){
int indexDiff = Math.abs(pair[i].index - pair[j].index);
if (indexDiff <= k) {
return true;
}
}
}
return false;
}