关闭

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

标签: leetcode
117人阅读 评论(0) 收藏 举报
分类:

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

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:37241次
    • 积分:1662
    • 等级:
    • 排名:千里之外
    • 原创:133篇
    • 转载:3篇
    • 译文:0篇
    • 评论:24条
    文章分类
    最新评论