Contains Duplicate III

题目

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
    }
}

转载于:https://my.oschina.net/zuoyc/blog/491286

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值