原文:
問題描述:
乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度是o(n),空間複雜度是o(1)。
按位異或性質:將數轉化成2進製,2個數相同異或為0,2數不同異或為1: 0^0=0,1^1=0;0^1=1。(與1異或,得該位元素的反,與0異或,得該位元素)
滿足結合律和交換律。
按位異或典型用途:
1、交換兩個整數的值而不必用第三個引數
a = 9, b = 11;
a=a^b; 1001^1011=0010
b=b^a; 1011^0010=1001
a=a^b; 0010^1001=1011
得到:a = 11,b = 9;
2、求乙個位串資訊的某幾位資訊的反。如欲求整型變數j的最右4位資訊的反,用邏輯異或運算015^j,就能求得j最右4位的資訊的反,即原來為1的位,結果是0,原來為0的位,結果是1。
本題思路:
如果乙個陣列,只有1個元素出現1次,其他元素都出現2次,將所有元素異或,結果即為出現1次的元素(相同元素異或為0,0與元素異或為本身)。
將題目中的陣列分成2個分別只含有1個出現1次的元素,其他都是出現2個的元素,即可使用上面的性質求解。
陣列分割:
將所有元素異或,即為2個不同的元素的異或,找到第乙個為1的位(不同),然後按照該位為1和為0的分成2個陣列,即為只含1個不同元素陣列。每個陣列中所有元素異或,記得到2個要找的不同的數
**:
[cpp]view plain
copy
#include
using
namespace
std;
void
findtwodiffnum(
int*arr,
intlen)
//不需要陣列分組,只要儲存異或結果即可
intleftresult=0 ,rightresult=0;
for(i=0;i
cout<' '
<
} int
main()
; findtwodiffnum(arr,8);
intarr2=;
findtwodiffnum(arr2,8);
system("pause"
);
return
0;
}
找出陣列中只出現一次的數
今天來看一道有意思的題,看起來很簡單,但是要想到滿足要求的答案沒那麼容易。有乙個非空整形陣列,除了有乙個只出現過一次的數,其他的數都出現且只出現過兩次,現要求找出這個只出現過一次的數。時間複雜度不能超過 o n 而且不能使用額外空間。大概意思就是,比如從 5,5,8,8,6,9,9 陣列中找出 6 ...
找出陣列中2個只出現一次的數字
題目 乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度是o n 空間複雜度是o 1 分析一下 這個問題有點特殊,而且不能按常規解法來求解,因為時間和空間達不到要求,常規解法比如 先排序,後找,重複的元素是挨在一起的,這樣時間複雜度為o nlo...
找出陣列中只出現過一次的數
乙個大陣列,在1到25000之間,只有4k memory,列印出其中正好只出現過一次的數。沒出現過,出現過2次,3次,或更多,都不列印。solutions 1 位圖法,但每個數有3個狀態 0,1,1.因此需要2 bit,25000 2 8 1024 6.1k,記憶體占用符合要求。2 壓縮,解法1中,...