剑指offer:找到数组中重复的值(C+Java)

题目:在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3.

 

分析:因为这个数组的长度是n并存放了n个数字,如果这个数组的数字没有重复,那么排序之后,它的数字和数组下标应该是一一对应的。那么由于数组中存在重复的数字,就会有些数字的下标没有对应的数字,而是对应其他数字。

具体怎么做?首先我们可以重排这个数组,假设该数组为a。从头开始,当扫描到下标为i的数字时,此时这个位置存放的值我们设为m。如果i=m,则跳到下标为i+1的数字;如果i≠m,则比较m与a[m]的值。如果m=a[m],那么我们就找到了重复的值了,如果不相等,则将m放到a[m]处,而a[m]放到a[i]处。接下来就是重复这个过程了。

我们以上面的a[7]={2,3,1,0,2,5,3}为例分析。

a[7]={2,3,1,0,2,5,3},a[0]=2,0≠2->a[2]=[1],2≠1=》a[7]={1,3,2,0,2,5,3};

a[7]={1,3,2,0,2,5,3},a[0]=1,0≠1->a[1]=[3],1≠3=》a[7]={3,1,2,0,2,5,3};

a[7]={3,1,2,0,2,5,3},a[0]=3,0≠3->a[3]=[0],3≠0=》a[7]={0,1,2,3,2,5,3};

接下来会一直到a[4];

a[7]={0,1,2,3,2,5,3},a[4]=2,4≠2->a[2]=2,这个时候就找到了重复的值了,搞定!

 

代码示例如下:

#include<stdio.h>

int duplicate(int numbers[],int length){
	int i,temp,duplicate;
	if(numbers == NULL || length <= 0)
		return -1;
	for(i = 0; i < length; ++i){
		if(numbers[i] < 0 || numbers[i] > length - 1)
			return -1;
	}

	for(i = 0; i < length; ++i){
		while(numbers[i] != i){
			if(numbers[i] == numbers[numbers[i]]){
				duplicate = numbers[i];
				return duplicate;
			}
			temp = numbers[i];
			numbers[i] = numbers[temp];
			numbers[temp] = temp;
		}
	}
	return -1;
}

int main(){
	int a[7] = {2,3,1,0,2,5,3};
	int length,i;

	length = sizeof(a)/sizeof(int);
	for(i = 0; i < length; i++)
		printf("%d ",a[i]);
	printf("\n");

	printf("%d\n", duplicate(a,7));

	for(i = 0; i < length; i++)
		printf("%d ",a[i]);
	printf("\n");

	return 0;
}
public class t1 {	
	public static int duplicate(int[] num,int len) {
		if(num == null || len <= 0) {
			return -1;
		}
		
		for(int i = 0; i < len; ++i) {
			if(num[i] < 0 || num[i] > len - 1)
				return -1;
		}
		
		for(int i = 0; i < len; ++i) {
			while(num[i] != i) {
				if(num[i] == num[num[i]]) {
					int n = num[i];
					return n;
				}
				int temp = num[i];
				num[i] = num[temp];
				num[temp] = temp;
			}
		}
		return -1;
	}
	
	public static void main(String[] args) {
		int[] number = {1,2,3,4,6,7,5,3};
		int length = number.length;
		System.out.println(duplicate(number,length));
		return;
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值