# 350. Intersection of Two Arrays II
題目:<https://leetcode.com/problems/intersection-of-two-arrays-ii/>
解法一:直接解,先用一個 hash table 來計數紀綠 num1 中數字的出現次數,叫做 countTable ,其中 countTable 的 key 為數字,value 為出現次數,接著找 nums2 的數字是否有在 countTable 出現,如果有的話,記錄到另一個 hash table,叫做 interTable,並減少 countTable 的次數記錄,最後將 interTable 傳換成 array 的形式輸出。
PS: python 使用內建的型態 dict,C 使用 leetcode 額外支援的型態 uthash。
Python3:
``` python 3
class Solution:
def intersect(self, nums1: list[int], nums2: list[int]) -> list[int]:
countTable = dict()
for num in nums1:
if num in countTable:
countTable[num] += 1
else:
countTable[num] = 1
interTable = dict()
for num in nums2:
if num in countTable:
if num in interTable:
interTable[num] += 1
else:
interTable[num] = 1
if countTable[num] > 1:
countTable[num] -= 1
else:
del countTable[num]
output = []
for num, count in interTable.items():
output += [num] * count
return output
if __name__ == '__main__':
nums1 = [1, 2, 2, 1]
nums2 = [2, 2]
ans = Solution().intersect(nums1, nums2)
print(ans)
```
C:
``` c
#include <stdio.h>
#include <stdlib.h>
#include "uthash.h"
typedef struct {
int key;
int value;
UT_hash_handle hh;
} hashEntry;
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
hashEntry *countTable = NULL;
hashEntry *cur = NULL;
for (int i = 0; i < nums1Size; i++) {
HASH_FIND_INT(countTable, &nums1[i], cur);
if (cur != NULL) {
cur->value += 1;
} else {
cur = (hashEntry*)malloc(sizeof(hashEntry));
cur->key = nums1[i];
cur->value = 1;
HASH_ADD_INT(countTable, key, cur);
}
}
hashEntry *interTable = NULL;
hashEntry *tmp = NULL;
for (int i = 0; i < nums2Size; i++) {
HASH_FIND_INT(countTable, &nums2[i], cur);
if (cur != NULL) {
HASH_FIND_INT(interTable, &nums2[i], tmp);
if (tmp != NULL) {
tmp->value++;
} else {
tmp = (hashEntry*)malloc(sizeof(hashEntry));
tmp->key = nums2[i];
tmp->value = 1;
HASH_ADD_INT(interTable, key, tmp);
}
if (cur->value > 1) {
cur->value--;
} else {
HASH_DEL(countTable, cur);
free(cur);
}
}
}
int *output = NULL;
*returnSize = 0;
int i = 0;
HASH_ITER(hh, interTable, cur, tmp) {
*returnSize += cur->value;
output = (int*)realloc(output, sizeof(int) * (*returnSize));
while (i < *returnSize)
output[i++] = cur->key;
HASH_DEL(interTable, cur);
free(cur);
}
HASH_ITER(hh, countTable, cur, tmp) {
HASH_DEL(countTable, cur);
free(cur);
}
return output;
}
int main()
{
int nums1[] = {1, 2, 2, 1};
int nums1Size = sizeof(nums1) / sizeof(nums1[0]);
int nums2[] = {2, 2,};
int nums2Size = sizeof(nums2) / sizeof(nums2[0]);
int returnSize;
int* ans = intersect(nums1, nums1Size, nums2, nums2Size, &returnSize);
for (int i = 0; i < returnSize; i++)
printf("%d\n", ans[i]);
return 0;
}
```
解法二:二元搜尋法,建立一個 output 陣列,將 nums1 排序,接著將 nums2 每個元素依序搜尋是否有在 nums1 中,有的話將此元素加入 output 陣列,並從 nums1 刪除此元素。
Python3:
``` python 3
class Solution:
def intersect(self, nums1: list[int], nums2: list[int]) -> list[int]:
def binarySearch(arr, target):
left = 0
right = len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] > target:
right = mid - 1
elif arr[mid] < target:
left = mid + 1
else:
return mid
return ~left
nums1.sort()
output = []
for num in nums2:
idx = binarySearch(nums1, num)
if idx >= 0:
output.append(num)
del nums1[idx]
return output
if __name__ == '__main__':
nums1 = [1, 2, 2, 1]
nums2 = [2, 2]
ans = Solution().intersect(nums1, nums2)
print(ans)
```
C:
``` c
#include <stdio.h>
#include <stdlib.h>
int binarySearch(int* arr, int arrSize, int target) {
int left = 0, right = arrSize - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] > target)
right = mid - 1;
else if (arr[mid] < target)
left = mid + 1;
else
return mid;
}
return ~left;
}
int cmpfunc (const void* a, const void* b) {
return (*(int*)a) - (*(int*)b);
}
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
qsort(nums1, nums1Size, sizeof(int), cmpfunc);
int * output = (int*)malloc(sizeof(int) * 1000);
*returnSize = 0;
for (int i = 0; i < nums2Size; i++) {
int idx = binarySearch(nums1, nums1Size, nums2[i]);
if (idx >= 0) {
output[(*returnSize)++] = nums2[i];
nums1Size--;
for (int j = idx; j < nums1Size; j++)
nums1[j] = nums1[j + 1];
}
}
return output;
}
int main()
{
int nums1[] = {4, 9, 5};
int nums1Size = sizeof(nums1) / sizeof(nums1[0]);
int nums2[] = {9, 4, 9, 8, 4};
int nums2Size = sizeof(nums2) / sizeof(nums2[0]);
int returnSize;
int * ans = intersect(nums1, nums1Size, nums2, nums2Size, &returnSize);
for(int i = 0; i < returnSize; i++)
printf("%d ", ans[i]);
printf("\n");
return 0;
}
```
###### tags: `leetcode` `hash table` `binary search`