20220926 - 217. Contains Duplicate 存在重复元素(手写哈希表)

57 阅读1分钟

Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct.

Example 1

Input: nums = [1,2,3,1]
Output: true

Example 2

Input: nums = [1,2,3,4]
Output: false

Example 3

Input: nums = [1,1,1,3,3,4,3,2,4,2]
Output: true

  Constraints

  • 1 <= nums.length <= 105
  • -109 <= nums[i] <= 109

Solution

分离链接法表示哈希表。写的时候有两个问题:

  • 主函数里传给插入函数的第二个参数应该是哈希函数值而不是查找函数的返回值,因为没有找到是返回 -1
  • 哈希函数中不能直接取模,应该先把键值进行同余运算调整为正数,类 C 语言负数取模还是负数
typedef struct LNode *PtrToLNode;
struct LNode {
    int val;
    PtrToLNode next;
};

typedef struct HashT *HashTable;
struct HashT {
    int tableSize;
    PtrToLNode elem;
};

int nextPrime(int N)
{
    int i, p;
    if (N == 1) return 2;
    p = (N % 2) ? N + 2 : N + 1;
    while (p <= 1000000) {
        for (i = (int)sqrt(p); i > 2; i--)
            if (!(p % i)) break;
        if (i == 2) break;
        else p += 2;
    }
    return p;
}

int hash(int key, int n){
    while (key < 0) key += n;
    return key % n;
}

HashTable createHashTable(int numsSize){
    HashTable H = (HashTable)malloc(sizeof(struct HashT));
    H->tableSize = nextPrime(numsSize);
    H->elem = (PtrToLNode)malloc(sizeof(struct LNode) * H->tableSize);
    for (int i = 0; i < H->tableSize; i++) {
        H->elem[i].val = 0xffffffff;
        H->elem[i].next = NULL;
    }
    return H;
}

int find(HashTable H, int item){
    int pos = hash(item, H->tableSize);
    PtrToLNode p = H->elem[pos].next;
    while (p) {
        if (p->val == item)
            return pos;
        p = p->next;
    }
    return -1;
}

void insert(HashTable H, int pos, int item){
    PtrToLNode newCell = (PtrToLNode)malloc(sizeof(struct LNode));
    newCell->val = item;
    newCell->next = H->elem[pos].next;
    H->elem[pos].next = newCell;
}

bool containsDuplicate(int* nums, int numsSize){
    HashTable H = createHashTable(numsSize);
    for (int i = 0; i < numsSize; i++) {
        int pos = find(H, nums[i]);
        if (pos == -1)
            insert(H, hash(nums[i], H->tableSize), nums[i]);
        else
            return true;
    }
    return false;
}

题目链接: 217. 存在重复元素 - 力扣(LeetCode)