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