如何找出數組中唯一的重復元素


數組a[N],1至N-1這N-1個數存放在a[N]中,其中某個數重復一次,寫一個函數, 找出被重復的數字。要求每個數組元素只能訪問一次,不用輔助存儲空間。

由於題目要求每個數組元素只能訪問一次,不用輔助存儲空間,可以從原理上入手,采用數學求和法,因為只有一個數字重復一次,而數又是連續的,根據累加和原理,對數組的所有項求和,然后減去1至N-1的和,即為所求的重復數。程序代碼如下:

#include "stdafx.h"
#include <stdio.h>

void xor_findDup(int *a, int N)
{
	int tmp1 = 0;
	int tmp2 = 0;
	for (int i = 0; i < N - 1; ++i)
	{
		tmp1 += (i + 1);
		tmp2 += a[i];
	}
	tmp2 += a[N - 1];
	int result = tmp2 - tmp1;
	printf("%d\n", result);
}
int main()
{
	int a[] = { 1, 2, 1, 3, 4 };
	xor_findDup(a, 5);
	getchar();
	return 0;
}

  效果如圖:

如果題目沒有要求每個數組元素只能訪問一次,不用輔助存儲空間,還可以用異或法和位圖法來求解。

(1)異或法

根據異或法的計算方式,每兩個相異的數執行異或運算之后,結果為1;每兩個相同的數異或之后,結果為0,任何數與0異或,結果仍為自身。所以數組a[N]中的N個數異或結果與1至N-1異或的結果再做異或,得到的值即為所求。

設重復數為A,其余N-2個數異或結果為B,N個數異或結果為A^A^B,1至N-1異或結果為A^B,由於異或滿足交換律和結合律,且X^X=0,0^X=X,則有(A^B)^(A^A^B)=A^B^B=A.

程序代碼如下:

#include "stdafx.h"
#include <stdio.h>

void xor_findDup(int * a, int N)
{
	int i;
	int result = 0;
	for (i = 0; i < N; i++)
	{
		result ^= a[i];
	}
	for (i = 1; i < N; i++)
	{
		result ^= i;
	}
	printf("%d\n", result);
}
int main()
{
	int a[] = { 1, 2, 1, 3, 4 };
	xor_findDup(a, 5);
	getchar();
	return 0;
}

(2)位圖法。

位圖法的原理是首先申請一個長度為N-1且均為0組成的字符串,字符串的下標即為數組a[]中的元素,然后從頭開始遍歷數組a[N],取每個數組元素a[j]的值,將其對應的字符串中的對應位置置1,如果已經置過1,那么該數就是重復的數。由於采用的是位圖法,所以空間復雜度比較大,為O(N).

程序示例如下:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
void xor_findDup(int * arr, int NUM)
{
	int *arrayflag = (int *)malloc(NUM*sizeof(int));
	int i = 1;
	while (i < NUM)
	{
		arrayflag[i] = false;
		i++;
	}
	for (i = 0; i < NUM; i++)
	{
		if (arrayflag[arr[i]] == false)
		{
			arrayflag[arr[i]] = true;
		}
		else
		{
			printf("%d\n", arr[i]);
			return;
		}
	}
}
int main()
{
	int a[] = { 1, 2, 1, 3, 4 };
	xor_findDup(a, 5);
	getchar();
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM