您的位置:首页 > 大数据 > 人工智能

Contains Duplicate III

2015-08-12 16:15 471 查看

题目

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.

We just call nums[i] and nums[j] friend element in this artical

思考

A sliding window is must

use a Binary Search Tree to store the element inside the window

search/insert/remove O(logK) in window

every time we move window by one step, we check the newest element: Does it has some friend element?

It is a search problem, you need to find element in the tree, since BST can provide good search performance. It is ok.

Code

import java.util.*;

/**
* Created by zuo on 15-8-12.
*/
public class ContainsDuplicatedIII {

/**
*
* @param nums
* @param k index diff, means the window can have k+1 element
* @param t value diff
* @return
*/
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if ( k <= 0 || t < 0) {
return false;
}
// the window start (included)
int winStart = 0;
// the window ends (included)
int winEnd = 0;

TreeMap<Integer, Set<Integer>> tree = new TreeMap<Integer, Set<Integer>>();

/**
* cauz winEnd should be included, initialize the window
*/
if (!tree.containsKey(nums[winEnd])) {
tree.put(nums[winEnd], new HashSet<Integer>());
}
tree.get(nums[winEnd]).add(winEnd);

while(winEnd < nums.length) {

/**
* reach criterion exception himself
*/
Map.Entry<Integer, Set<Integer>> ceilingEntry = tree.ceilingEntry(nums[winEnd] - t);
Map.Entry<Integer, Set<Integer>> floorEntry = tree.floorEntry(nums[winEnd] + t);
if ((ceilingEntry != null && (ceilingEntry.getKey() != nums[winEnd] || ceilingEntry.getValue().size() > 1) ) || (floorEntry != null && (floorEntry.getValue().size() > 1 || floorEntry.getKey() != nums[winEnd]))) {
return true;
}

/**
* ready for next epoch
* now the window has (winEnd - winStart + 1) elements(window size = element count)
* winStart++ if the window reach biggest
*/
winEnd++;
if (winEnd == nums.length) {
break;
}
if (!tree.containsKey(nums[winEnd])) {
tree.put(nums[winEnd], new HashSet<Integer>());
}
tree.get(nums[winEnd]).add(winEnd);
if (winEnd - winStart > k) {
if (tree.containsKey(nums[winStart])) {
tree.get(nums[winStart]).remove(winStart);
if (tree.get(nums[winStart]).size() == 0) {
tree.remove(nums[winStart]);
}
}
winStart++;
}
}
return false;
}

public static void main(String[] args) {
ContainsDuplicatedIII containsDuplicatedIII = new ContainsDuplicatedIII();
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{1, 3 ,1 }, 1, 1));//f
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{1, 2}, 1, -1));//f
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{1}, 1, 1));//f
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{1,2,3,4,5}, 1,3)); //t
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{1,3,5,3,1}, 1,3));//t
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{1,1,1}, 1,0));//t
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{1,2,3}, 1,0));//f
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{1,1,1}, 0,1));//f
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{ -1 , - 1}, 1, 0));//t`
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{ 1,3,1}, 2, 1));//t
System.out.println(containsDuplicatedIII.containsNearbyAlmostDuplicate(new int[]{ 4,1,6,3}, 100, 1));//t
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: