劍指offer--位運算(22、34、63)

offer22

輸入一個整數,求該整數的二進制表達中有多少個1。例如輸入10,由於其二進制表示爲1010,有兩個1,因此輸出2

典型的位運算題目

void bit_find(const int& num,int* bit_array){
	int i,mask;
	mask=1;
	for(i=31;i>=0;i--){
		bit_array[i]=(bool)(num&mask);
		mask=mask<<1;
	}
}

編程之美上有更好的解法,以後再說


offer34

一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。要求時間複雜度是O(n),空間複雜度是O(1)

我們還是從頭到尾依次異或數組中的每一個數字,那麼最終得到的結果就是兩個只出現一次的數字的異或結果。因爲其他數字都出現了兩次,在異或中全部抵消掉了。由於這兩個數字肯定不一樣,那麼這個異或結果肯定不爲0,也就是說在這個結果數字的二進制表示中至少就有一位爲1。我們在結果數字中找到第一個爲1的位的位置,記爲第N位。現在我們以第N位是不是1爲標準把原數組中的數字分成兩個子數組,第一個子數組中每個數字的第N位都爲1,而第二個子數組的每個數字的第N位都爲0

現在我們已經把原數組分成了兩個子數組,每個子數組都包含一個只出現一次的數字,而其他數字都出現了兩次。因此到此爲止,所有的問題我們都已經解決。

這段分析碉堡了。


int FindBit(int *a,int len)
{
	int i,n;
	n=a[0];
	for (i=1;i<len;i++)
	{
		n=n^a[i];
	}

	for (i=0;i<32;i++)
	{
		if (n&(i<<i))
		{
			return i;
		}
	}
}

void FindNum(int *a,int len,int &num1,int &num2)
{
	int nBit=FindBit(a,len);
	int i;
	num1=num2=0;
	for (i=0;i<len;i++)
	{
		if (a[i]&(i<<nBit))
		{
			num1=num1^a[i];
		}
		else
		{
			num2=num2^a[i];
		}
	}

}

offer63

一個數組中有三個數字a、b、c只出現一次,其他數字都出現了兩次。請找出三個只出現一次的數字。

這個題目還沒搞懂

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章