1. 程式人生 > >C++ 演算法之 陣列中只出現一次的數字

C++ 演算法之 陣列中只出現一次的數字

題目:

一個整型數組裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度為O(n),控制元件複雜度為O(1)

演算法思路:

如果一個數組當中,只要一個數字出現一次,其他都是出現兩次,那麼我們只要把所有的數進行異或得到的就是結果

現在有兩個數字出現一次,那麼我們還是異或所有的數,最後的到的結果就是這兩個不想等的數字的異或結果

比如 2 4 3 6 3 2 5 5 最後異或就是 4 與 6 異或,那麼它們兩個異或的結果肯定不是0;也就是說這個結果數字的二進位制

當中至少有一位是1;我們在這個結果數字當中找到第一個為1的位置,記為第n位,現在我們以第n位是不是1把原來的

陣列分為兩部分;再分別異或兩個陣列;

分組異或:

比如int a[] = {1, 1, 3, 5, 2, 2}

    整個陣列異或的結果為3^5 0x0011 ^ 0x0101 = 0x0110

    對0x0110,第1位(由低向高,從0開始)就是1。因此整個陣列根據第1位是0還是1分成兩組。

a[0] =1  0x000第一組

a[1] =1  0x000第一組

a[2] =3  0x001第二組

a[3] =5  0x010第一組

a[4] =2  0x001第二組

a[5] =2  0x001第二組

第一組有{1, 1, 5},第二組有{3, 2, 3},明顯對這二組分別執行“異或”解法就可以得到53了。

// FindNumAppearOnce.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

//找到第一個為1的位置
unsigned int FindFirstBitis1(int num)
{
	int indexBit = 0;
	while (((num & 1) == 0) && (indexBit < 8 * sizeof(int)))
	{
		num = num>>1;
		++indexBit;
	}

	return indexBit;
}
bool IsBit1(int num , unsigned int indexBit)
{
	num = num >> indexBit;
	return (num & 1);
}

void FindNumAppearOnce(int array[], int nLength, int& num1, int& num2)
{
	if (array == NULL || nLength < 2)
	{
		return;
	}
	int resultXOR = 0;
	for (int i = 0; i < nLength; i++)
	{
		resultXOR ^=array[i];
	}

	//找到抑或結果數字當中的第一個1的位置
	unsigned int indexOf1 = FindFirstBitis1(resultXOR);
	num1 = num2 = 0;
	for (int j = 0; j < nLength; ++j)
	{
		if (IsBit1(array[j],indexOf1))
		{
			num1^=array[j];
		}
		else
		{
			num2^= array[j];
		}
	}
}
int _tmain(int argc, _TCHAR* argv[])
{

	int array[] ={4,6,1,1,1,1};
	int i = 0;
	int j = 0;
	FindNumAppearOnce(array,sizeof(array)/sizeof(array[0]),i,j);
	if (i == 0 && j != 0)
	{
		cout<<"您輸入的陣列的當中出現1次的只有一個數字,它是:"<<j<<endl;
	}
	else if (j == 0 && i != 0)
	{
		cout<<"您輸入的陣列的當中出現1次的只有一個數字,它是:"<<i<<endl;
	}
	else if (i == 0 && j == 0)
	{
		cout<<"您輸入的陣列當中沒有隻出現一次的數字"<<endl;
	}
	else
	{
		cout<<"您輸入的陣列當中只出現1次的兩個數字是"<<i<<" "<<j<<endl;
	}
	

	getchar();
	return 0;
}
實現這個程式碼的假設條件就是  陣列當中不會出現兩個以上只出現1次的數字,比如 1 2 3 4 5 6 7 8 這種情況是無法處理的!