【Leetcode349 -两个数的交集 Interesection of Two Arrays】(C语言)

这篇博客详细介绍了如何用C语言解决LeetCode上的349题,即找到两个数组的交集。内容包括题目分析、简单的思路、代码整理和优化版本,最终提供了一个高效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

目录

 

两个数的交集

测试单元

题目分析

(1)简单思路版

(2)整理版

(3)优化版本

大功告成


两个数的交集

给定两个数组,编写一个函数来计算它们的交集。

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

大功告成

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值