昨天拼多多面試中遇到了這個問題:乙個1~n的自然數的亂序陣列,其中缺失了1到n之間的某個數,如何快速找出這個數?
題意:已知乙個有序數列1-n(元素值)中缺少了乙個元素,找出這個元素。
1、異或可解 時間複雜度o(n)
異或有個很巧妙的地方:同一變數和該變數與另一變數的異或值的異或等於這個變數自身。所以我們可以把1~n的所有數異或,再把陣列**現的所有數異或,然後再把這兩個異或的結果異或,最後得到的值即為我們要找的值。這樣時間複雜度為o(n),空間複雜度為o(1)。在空間上比第二種方法要好,而且不會出現第一種方法中所說的溢位問題。
a=[0
,1,2
,3,4
,6,7
]n=7xor0=
0for i in
range(1
,n+1):
print
(i) xor0=xor0^i
xor1=a[0]
for i in
range(1
,n):
xor1=xor1^a[i]
print
(xor0^xor1)
2、二分 時間複雜度o(lgn)
3、求和
當n不太大時,可以考慮求和。先算出1~n的所有數的和,然後減去陣列**現的所有自然數的和。時間複雜度為o(n),空間複雜度o(1)。這種方法的缺點是n不能太大,n比較大時,求和容易溢位。
4、位圖。從頭到尾的掃瞄整個陣列,把出現的數相應的位設定為1.然後再掃瞄位圖,找出不為1的那一位,即為要找的數。這種方法的時間複雜度為o(n),空間複雜度為o(n)。
#二分查詢有序陣列中缺失的乙個元素,時間複雜度盡可能低
defbsearch
(a,left,right)
:while
(left+
1:print
(left,
" ",right)
mid=left+
(right-left)//2
#這種情況說明缺失的元素在前面
if(a[mid]
==mid+1)
: left=mid+
1elif
(a[mid]
==mid+2)
: right=mid-
1return left+
1def
findmis
(a,n)
:return bsearch(a,
0,n-1)
a=[1,
2,4,
5,6,
7,8,
9]n=9
print
(findmis(a,n)
)
放在a中(打亂順序),以時間複雜度為o(n)的演算法找到減少的這2個數
【思路】:如果是減少1個數,那麼大家都知道方法——迴圈一次,求a的和sum以及(1+2+…+n)=sum,然後用sum-sum就能得到結果。可是,現在出現2個數,那麼導致只求和是不行的,那麼請問能怎麼辦?那就通過別的運算記錄更多的資訊!四則運算有加減乘除嗎?別老是記著+,把別的兄弟都給忘了!
求乙個數中1的個數
碰到遇到乙個有趣的題,求乙個數二進位制的表示中1的個數,該題有兩種解法,一種是使用短除法將該數直接轉化為二進位制數,另一種比較巧妙的演算法是使用與運算,原理如下圖所示 依照此種思入有如下演算法 int numberof1 solution3 int i return count 依照短處法的思路 有...
求乙個數的質因數(1個或n個)
在做 容斥原理 題時經常需要求出乙個數的質因子,而且不是所求數的位數很多,就是一次求n多數的質因子。下面分別給出兩種型別的 供拋磚引玉。第一種型別 用於每次只能求出乙個數的質因子,適用於題目中給的n的個數不是很多,但是n又特別大的情況。includeint main if n 1 應對 n 103 ...
計算乙個數中1的個數 0的個數
1.求乙個int數二進位制中1的個數 1 與1 右移 正數 負數都可以 計算的是負數補碼中1的個數 inta cin a int count 0 int n sizeof int 8 位數for int i 0 i a 1 右移一位 cout 2 右移相當於除以2 判斷最低位可用2取餘 右移可用除以...