2014-04-19 找重复值(逻辑思维题)

题目:

取值为[1,n-1]含n个元素的整数数组至少存在一个重复数,O(n)时间内找出其中任意一个重复数。如A[]={1,2,2,4,5,4},则2和4均是重复元素。


思想:

(1)如果这n个元素中只含有一个重复的数,那么我们只需要求数组A的和,然后减去这1,2,3...n-1即得到重复的数。


(2)很容易想到排序,但如果是比较排序的想法,时间复杂度会达到O(NlogN);此时我们可以利用数与下标之间的关系来确定,首先明确一点所有的数均小于n;那我们开始从index=0到index=length-1遍历数组,过程如下:

(2.1)A[index]<n,则temp=A[index],否则temp=A[index]-n。

(2.2)若A[temp]<n,表示数值A[temp]未被访问过,更新A[temp]=A[temp]+nA[temp] >= n,表示数值A[temp]已被访问过,直接返回temp。


(3)上述思想归根到底是采用了一种hash冲突的思想,根据所有的数均小于n,来进行处理的;由于只遍历一遍数组,故时间复杂度为O(n),只用到常数个变量,故空间复杂度为O(1)。




程序实现:

#include<stdio.h>
#include<stdlib.h>

int find_number(int *A, int n)
{
	int temp;
	int index;
	for(index = 0; index < n; index++){
		if(A[index] < n){
			temp = A[index];
		}else{
			temp = A[index] - n;
		}

		if(A[temp] < n){
			A[temp] += n;
		}else{
			return temp;
		}
	}
	
	return -1;
}

int main(void)
{
	int A[] = {4,6,7,8,1,7,3,4,4};
	
	int i;
	printf("A[]:");
	for(i = 0; i < sizeof(A) /sizeof(A[0]) ; i++){
		printf("%d ", A[i]);
	}
	printf("\n");

	int a = find_number(A,  sizeof(A) /sizeof(A[0]));
	printf("search numbers:%d\n", a);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值