剑指offer--面试题3:数组中重复的数字

本文介绍三种不同的算法来找出数组中重复的数字,并分析了每种方法的时间和空间复杂度。第一种方法通过交换元素实现,第二种方法利用数组值加数组长度的方式标记已访问的数字,第三种方法采用二分查找策略。

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

#include<stdio.h>
void swap(int *x,int *y)
{
	int temp=*x;
	*x=*y;
	*y=temp;
}
int duplicate_1(int A[],int length)
{//思想:遍历数组,假设遇到数字j,则将j换到下标为j的位置上,若再遇到相同数字j,对应位置上的数字已经==j。返回。
	if(A==NULL||length<=0)
		return 0;
	for(int i=0;i<length;++i)
		if(A[i]<0||A[i]>length-1)
			return 0;
	for(i=0;i<length;++i)
		while(A[i]!=i)
		{
			if(A[i]==A[A[i]])
				return A[i];
			swap(&A[i],&A[A[i]]);
		}
		return 0;
}//时间复杂度=O(n),空间复杂度=O(1)


bool duplicate_2(int numbers[],int length,int *duplication)
{//思想:遍历数组,假遇到数字j,则将下标为j的位置上的数字+n。再遇到相同数字时,对应位上的数字已经>=n。返回。
	if(numbers==NULL||length<=0)
		return false;
	for(int i=0;i<length;++i)
		if(numbers[i]<0||numbers[i]>length-1)
			return false;
	for(i=0;i<length;++i)
	{
		int index=numbers[i];
		if(index>=length)
			index-=length;
		if(numbers[index]>=length)
		{
			*duplication=index;
			return true;
		}
		numbers[index]+=length;
	}
	return false;
}//时间复杂度=O(n),空间复杂度=O(1)
void main()
{
	int result_1;
	int arr_1[7]={2,3,1,0,2,5,3};
	
	result_1=duplicate_1(arr_1,7);
	if(result_1)
		printf("方法1:找到一个重复的数字是:%d\n",result_1);
	else
		printf("方法1:没有重复的数字或返回错误!\n");
//***********************************************************************
	int result_2;
	bool res_2;
	int arr_2[7]={2,3,1,0,2,5,3};
	
	res_2=duplicate_2(arr_2,7,&result_2);
	if(res_2)
		printf("方法2:找到一个重复的数字是:%d\n",result_2);
	else
		printf("方法2:没有重复的数字或返回错误!\n");
}



#include<stdio.h>
int Count(const int* A,int length,int start,int end)
{
	if(A==NULL)
		return 0;
	int count=0;
	for(int i=0; i<length; ++i)
		if(A[i]>=start && A[i]<=end)
			++count;
	return count;
}
int duplicate(const int *A,int length)
{//二分查找法
	if(A==NULL || length<=0)
		return -1;
	for(int i=0; i<length ;++i)
		if(A[i]<1 || A[i]>length-1)
			return -1;
	for(int start=1,end=length-1 ;end >= start;)
	{
		int middle=((end-start)>>1)+start;
		int count=Count(A,length,start,middle);
		if(end==start)
		{
			if(count>1)
				return start;
			else
				break;
		}
		if(count>(middle-start+1))
			end=middle;
		else
			start=middle+1;
	}
	return -1;
}//时间复杂度=O(nlogn),空间复杂度=O(1)
void main()
{
	int result;
	int arr[8]={2,3,5,4,3,2,6,7};
        result=duplicate(arr,8);
	if(result!=-1)
		printf("方法3:找到一个重复的数字是:%d\n",result);
	else
		printf("方法3:没有重复的数字或返回错误!\n");
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值