Leetcode 217. Contains Duplicate & 219. Contains Duplicate II & 220. Contains Duplicate III

原创 2016年05月31日 01:05:38

217. Contains Duplicate

Total Accepted: 92421 Total Submissions: 221846 Difficulty: Easy

Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the 

array, and it should return false if every element is distinct.


思路:

hashmap或者hashset。有重复就return。

public class Solution {
    public boolean containsDuplicate(int[] nums) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int i=0; i<nums.length; i++){
            if(!map.containsKey(nums[i])) map.put(nums[i],1);
            else return true;
        }
        return false;
    }
}


public class Solution {
    public boolean containsDuplicate(int[] nums) {
        int len = nums.length;
        if (len==0) return false;
        
        HashSet <Integer> set = new HashSet <Integer>();
        for (int i=0; i< len; i++){
            if (set.contains(nums[i])) return true;
            set.add (nums[i]);
        }
        return false;
    }
}


219. Contains Duplicate II

Total Accepted: 60133 Total Submissions: 198719 Difficulty: Easy

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] 

and the difference between i and j is at most k.


思路:

用HashMap。Key是当前元素,value是location。从前往后,如果有该元素,并且value之差小于k则return,否则更新当前value值(从前往后扫,距离只会越来越大)。

public class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int i=0; i<nums.length; i++){
            if(!map.containsKey(nums[i])) map.put(nums[i],i);
            else if(i-map.get(nums[i])<=k) return true;
            else map.put(nums[i], i);
        }
        return false;
    }
}


220. Contains Duplicate III

Total Accepted: 28920 Total Submissions: 154344 Difficulty: Medium

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.


从AC率就可以看出这个题corner  case比较讨厌。

解法大致有二。


解法一:

使用TreeSet(内部封装了TreeMap)。保持该TreeSet的size,这样能保证从前往后扫的时候k符合要求。然后利用 ceiling函数来找比当前元素-t大的next元素。

之前已经保证里面只有K个元素,于是当前要保证得到的元素在上限当前元素+t的范围内。比如[4,2]这时候里面有4了,t是1,找比2-1大的元素找到了4,但是是不符合要求的。


需要注意几点:

1. t<0应该直接返回false。

2. -t和+t时需要处理overflow。


代码中有俩版本,一个是强制转换成long来判断。或者用version2,把a-b<c变成a<b+c。a+b>c变成a>c-b。

public class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        if (t<0) return false;  
        TreeSet<Integer> set = new TreeSet<Integer>();
        int start=0;
        for(int i=0; i<nums.length; i++){ 
            if(i-start>k) set.remove(nums[start++]); // make sure we have k elements in the set at most
            
            // version 1: use long, remember to use (long) to convert type
            // long l = (long) nums[i]-t; long h = (long) nums[i]+t;
            // int low = l < Integer.MIN_VALUE? Integer.MIN_VALUE : nums[i]-t;
            // int high = h > Integer.MAX_VALUE? Integer.MAX_VALUE : nums[i]+t;
            
            // verson 2: smarter way: a - b < c, a - b too small, then use b + c so that nothing overflow
            int low = nums[i] < Integer.MIN_VALUE + t ? Integer.MIN_VALUE : nums[i]-t;
            int high = nums[i] > Integer.MAX_VALUE - t ? Integer.MAX_VALUE : nums[i]+t;
            
            // make sure the element is in range [-t, t], ceiling return the NEXT element larger than low
            if(set.ceiling(low) !=null && set.ceiling(low)<=high) return true;
            set.add(nums[i]);
        }
        return false;
    }
}

解法二:

如果直接排序,利用bst是可以logn发现符合t要求的元素,但是这样index信息就丢失了,我们还要保证index符合要求。于是可以新建一个class保持val和index的信息。这样排序按val排序。之后取出符合t要求的元素之后再对比index是否符合要求。

public class Solution {  
   public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
    if(nums.length < 2 || k < 1 || t < 0) return false;
    
    ValuePosPair[] valPosArr = new ValuePosPair[nums.length];
    for(int i = 0; i < nums.length; i++) valPosArr[i] = new ValuePosPair(nums[i],i);
    Arrays.sort(valPosArr);
    
    // [-3,3]
    // 2
    // 4
    // id -  1 !=i make sure we do have a target, because we need the target to be in range of nums[i], nums[i]+t
    
    for(int i = 0; i < valPosArr.length; i++){
        int id = search(valPosArr, i, nums.length, valPosArr[i].val + t);
        if(id != -1 && id - 1 != i && id - 1 >= 0 && id - 1 < nums.length && Math.abs(valPosArr[i].pos - valPosArr[id - 1].pos) <= k) 
        return true;
    }
    return false;
    }
    
    // first value > t, r is len
    int search(ValuePosPair[] vs, int l, int r, long t){
        if(l > r) return -1;
        if(l == r) return vs[l].val > t ? l : -1;
        while(l < r){
            int m = l + (r - l) / 2;
            if(vs[m].val <= t) l = m + 1;
            else r = m;
        }
        return r;
    }
    
    class ValuePosPair implements Comparable<ValuePosPair>{
    
        int val;
        int pos;
        
        ValuePosPair(int v, int p) { val = v; pos = p;}
    
        public int compareTo(ValuePosPair x){
            return this.val - x.val;
        }   
    }
 }  

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

217, 219,220. Contains Duplicate I, II, III

Given an array of integers, find if the array contains any duplicates. Your function should return ...

Contains Duplicate III - LeetCode 220

题目描述: Given an array of integers, find out whether there are two distinct indices i and j in the ar...
  • bu_min
  • bu_min
  • 2015年06月01日 22:44
  • 413

[leetcode ]220.Contains Duplicate III

题目: Given an array of integers, find out whether there are two distinct indices i and j in the arra...

【LEETCODE】220-Contains Duplicate III

Given an array of integers, find out whether there are two distinct indices i and j in the array  ...

Leetcode 220. Contains Duplicate III

Given an array of integers, find out whether there are two distinct indices i and j in the array suc...

[LeetCode]217. Contains Duplicate&219. Contains Duplicate II&220. Contains Duplicate III

217. Contains Duplicate 219. Contains Duplicate II 220. Contains Duplicate III

leetcode: (219) Contains Duplicate II

【Question】 Given an array of integers and an integer k, find out whether there are two distinct ind...
  • zk031
  • zk031
  • 2015年08月28日 20:50
  • 176

Leetcode220-Contains Duplicate III

Given an array of integers, find out whether there are two distinct indices i and j in the array suc...

【leetcode】219. Contains Duplicate II

一、题目描述 Given an array of integers and an integer k, find out whether there are two distinct indic...

LeetCode笔记:219. Contains Duplicate II

判断一个数组中一定范围内是否有相同的数字
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Leetcode 217. Contains Duplicate & 219. Contains Duplicate II & 220. Contains Duplicate III
举报原因:
原因补充:

(最多只允许输入30个字)