目录
两个数的交集
给定两个数组,编写一个函数来计算它们的交集。
示例1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]
示例2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [9,4]
说明:
- 输出结果中的每个元素一定是唯一的。
- 我们可以不考虑输出结果的顺序。
测试单元
题目中已给出测试用例,习惯还是先写测试用例代码如下:
int main()
{
//int nums1[] = { 61, 24, 20, 58, 95, 53, 17, 32, 45, 85, 70, 20, 83, 62, 35, 89, 5, 95, 12, 86, 58, 77, 30, 64, 46, 13, 5, 92, 67, 40, 20, 38, 31, 18, 89, 85, 7, 30, 67, 34, 62, 35, 47, 98, 3, 41, 53, 26, 66, 40, 54, 44, 57, 46, 70, 60, 4, 63, 82, 42, 65, 59, 17, 98, 29, 72, 1, 96, 82, 66, 98, 6, 92, 31, 43, 81, 88, 60, 10, 55, 66, 82, 0, 79, 11, 81 };
//int nums1[] = = { 5, 25, 4, 39, 57, 49, 93, 79, 7, 8, 49, 89, 2, 7, 73, 88, 45, 15, 34, 92, 84, 38, 85, 34, 16, 6, 99, 0, 2, 36, 68, 52, 73, 50, 77, 44, 61, 48 };
int nums1[] = { 1, 2, 2, 1 };
int nums2[] = { 2, 2 };
int size = 0;
int *rn = NULL;
int *returnSize = (int *)malloc(sizeof(int));
rn = intersection(nums1, sizeof(nums1) / sizeof(int), nums2, sizeof(nums2) / sizeof(int), returnSize);
size = *returnSize;
for (int i = 0; i < size; i++)
{
printf("%d ", rn[i]);
}
system("pause");
return 0;
}
题目分析
寻找两个数组的交集,且交集里不能存在重复的项。
暴力穷举法:两数组一一比对,相同则存入在动态开辟的数组里不同则进行下一个比对。
1.如果交集数组里已经有数,则需将两个数组相同的数与交集数组内的数遍历一遍进行比较,相同(重复交集)则跳出循环,进行下一组数(两个给出数组)组比较。
2.如果不同则存入其中。
直到把两个数组全部遍历完。返回交集数组,将(参数)returnSize度置为交集数组长度
(1)简单思路版
#define _CRT_SECURE_NO_WARNINGS 1
#include "test.h"
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
assert(nums1 || nums2);
int size = nums1Size > nums2Size ? nums2Size : nums1Size;
*returnSize = 0;
int* rn = (int *)malloc(sizeof(int)*size);
int n = 0;
int flag = 0;//标记法 已有交集
for (int i = 0; i < nums1Size; i++){
int h = 0;//标记 是否是重复项
for (int j = 0; j < nums2Size; j++){
if (nums1[i] == nums2[j]){
if (flag == 1){
for (int x = 0; x <= n; x++){
if (rn[x] == nums1[i]){
h = 1;
break;
}
}
if (h == 1)
break;
else
{
rn[n] = nums1[i];
n++;
//break;
}
}
else{
rn[n] = nums1[i];
n++;
flag = 1;
//break;
}
}
}
}
*returnSize = n;
return rn;
}
(2)整理版
由于上述版本看起来比较费劲但是思路简单一点,整理后代码如下:
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
int i, j, k = 0, flag = 0;
int lens = nums1Size > nums2Size ? nums1Size : nums2Size;
int* re = (int*)malloc(sizeof(int)*lens);
if (nums1Size == 0) { *returnSize = k; return nums1; }
if (nums2Size == 0) { *returnSize = k; return nums2; }
for (i = 0; i < nums1Size; i++)
{ //flag用来标识数组re中是否已经存在nums1和nums2的交集,flag==0,则只要比较nums2[j]==nums1[i]即可。
if (flag == 0)
for (j = 0; j < nums2Size; j++)
{
if (nums2[j] == nums1[i])
{
flag = 1; re[k++] = nums1[i];
break;
}
}
//flag==1说明re中已存在交集数字,则nums1[i]还需要与re数组中的每个元素进行比较,保证输出结果中的每个元素一定是唯一的。
else if (flag == 1)
{
int t, f = 0;
for (t = 0; t < k; t++)
if (nums1[i] == re[t])
{
f = 1;
break;
}
if (f == 1)
continue;
for (j = 0; j < nums2Size; j++)
{
if (nums2[j] == nums1[i])
{
flag = 1; re[k++] = nums1[i];
break;
}
}
}
}
*returnSize = k;
return re;
}
(3)优化版本
假如事先将比较两数组进行排序,那么对于重复项的处理就可以更加简单明了代码如下:
int comp(const void *a, const void *b)//比较函数
{
return *(int*)a - *(int*)b;
}
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize)
{
qsort(nums1, nums1Size, sizeof(int), comp);//排序
qsort(nums2, nums2Size, sizeof(int), comp);
int i = 0, j = 0, k = 0;
int *rn = (int*)malloc(sizeof(int)* (nums1Size > nums2Size ? nums2Size : nums1Size));
while (i < nums1Size && j < nums2Size){
if (nums1[i] == nums2[j])//两数组值相等时
{
if (k < 1 || nums1[i] != rn[k - 1])//数组与现有交集没有出现重复项,和交集数组没有值时。
{
rn[k++] = nums1[i];
}
i++; //出现重复项则跳过这一组数
j++;
}
else if (nums1[i] < nums2[j])//两组数值不相等时且nums1[i]值小于nums2[j]的值,由于两数组是有升序的。则nums1下标加1。
{
i++;
}
else//反之nums2小标加1。
j++;
}
*returnSize = k;//数组长度
return rn;
}
大功告成