PU Contains Duplicate II

Jan 01, 1970

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 absolute difference between i and j is at most k.

C Solution:

struct He {
    int val;
    struct He *next;
};

struct Ht {
    int size;
    struct He **list;
};

struct Ht *create(void) {
    struct Ht *ht = malloc(sizeof(struct Ht));
    ht->size = 1000;
    ht->list = calloc(ht->size, sizeof(struct He *));
    return ht;
}

bool find_or_insert(struct Ht *ht, int val) {
    int ind = val % ht->size;
    if (ind < 0) ind = -ind;
    struct He *p = ht->list[ind];
    while (p) {
        if (p->val == val) return true;
        p = p->next;
    }
    p = malloc(sizeof(struct He));
    p->val = val;
    p->next = ht->list[ind];
    ht->list[ind] = p;
    return false;
}

void delete(struct Ht *ht, int val) {
    int ind = val % ht->size;
    if (ind < 0) ind = -ind;
    struct He **p = &(ht->list[ind]);
    while (*p) {
        if ((*p)->val == val) {
            struct He *tmp = (*p)->next;
            free(*p);
            *p = tmp;
            return;
        }   
        *p = (*p)->next;
    }
}

bool containsNearbyDuplicate(int* nums, int numsSize, int k) {
    if (k < 1) return false;
    struct Ht *ht = create();
    int i;
    for (i = 0; i < numsSize; i++) {
        if (find_or_insert(ht, nums[i])) return true;
        if (i >= k) {
            delete(ht, nums[i - k]);
        }
    }
    return false;
}

Python Solution 1:

class Solution(object):
    def containsNearbyDuplicate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: bool
        """
        d = collections.defaultdict(int)
        for i, val in enumerate(nums):
            if i > k: d[nums[i - k - 1]] -= 1
            if d.get(val, 0): return True
            d[val] += 1
        return False

Python Solution 2:

class Solution(object):
    def containsNearbyDuplicate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: bool
        """
        d = {}
        for i, val in enumerate(nums):
            if val in d and i - d[val] <= k: return True
            d[val] = i
        return False

Summary:

  1. There are two ways, first is delete the old element, second is remember the index.
  2. 19ms, 70.97%

LeetCode: 219. Contains Duplicate ||