本次總結在陣列中查詢特定的元素。
碰到的面試題目主要包括:
題目的意思很明顯,1001個數字中只有乙個數字出現了兩次,其餘的都是一次。並且不缺少任何數字。那麼找到這個數字,我們可以有很多思路:
思路a:求和,最簡單也最容易想出來的方法 1+2+3+4+。。。+1000的和與陣列的和求差,差的結果就是這個數字,缺點是,求和的話,結果可能會溢位。不妨看思路2
思路b:異或,位操作總有讓你驚喜的地方,原理是:
@ 如果兩個相同的數求異或,那麼結果為0。
@ 0與乙個數異或的結果為這個數
@ a^b ^a = b ;a^b^b = a;
據此,可以對陣列的元素與1,2,34,56,7,8...1000依次異或,最後的結果就是出現兩次的數字。
相應的**如下:
[cpp]view plain
copy
print?
#include
#include
intfindthenum(
int*a)
return
k;
} main()
a[1000] = rand()%1000;
printf("the num : %d %d \n"
,a[1000],findthenum(a));
return
0;
}
@onlyonename
假設這兩個數為a,b,將陣列中所有元素異或結果x=a^b,判斷x中位為1的位數(注:因為a!=b,所以x!=0,我們只需知道某乙個位為1的位數k,例如0010 1100,我們可取k=2或者3,或者5),然後將x與陣列中第k位為1的數進行異或,異或結果就是a,b中乙個,然後用x異或,就可以求出另外乙個。
據此,不難寫出**:
[cpp]view plain
copy
print?
#include
void
getnum(
inta,
intlen,
int&one,
int&two)
inttemp = res;
intk = 0;
while
(!(temp&1))
temp = 0;
for(
inti = 0;i
} one = temp ;
two = temp^res;
} int
main();
intone ,two;
getnum(a,8,one,two);
printf("%d --- %d \n"
,one,two);
return
0;
}
這題可以充分看到位運算的強大。
以該題為例,演算法的掃瞄過程如下圖所示:
類似這種找「第一次出現一次的數字(字元)」的題目有乙個共同的特點:數字或字元的範圍是確定的。因此我們可以考慮計數。具體思路是:首先掃瞄一次原陣列,記錄每個數字的出現次數,然後再一次掃瞄原陣列,並查詢其出現的次數,一旦遇到出現次數為1的數字,那麼就返回這個數字即可。相應的**如下:
[cpp]view plain
copy
print?
#include
#include
#define n 1000
intgetfirstone(
int*a,
intn)
for(
inti = 0;i
} }
intmain();
printf("%d \n"
,getfirstone(a,9));
}
這個題目有一種演算法叫做蓄水池抽樣,思路大致是這樣的,先選中前m個, 從第m+1個元素到最後乙個元素為止, 以m/i (i=m+1, m+2,...,n) 的概率選中第i個元素, 並且隨機替換掉乙個原先選中的元素, 這樣遍歷一次得到m個元素, 可以保證完全隨機選取。
相應的**如下:(這裡只說明原理,注意rand()函式並不是真正意義上的隨機數,具體可見:
[cpp]view plain
copy
print?
#include
#include
#define n 10000
#define m 20
intgetrandm(
int*a,
intn,
int*result,
intm)
for(j = i; j
} }
intmain()
intoutstream[m];
getrandm(instream,n,outstream,m);
for(
inti = 0;i
printf("%d "
,outstream[i]);
} printf("\n"
);
}
另:在有序陣列中查詢符合條件的兩個數字的解法見:雙指標法的應用:
在陣列中找k個數的和為m的演算法。
其他有關陣列中選取特定元素的題目待補充。
陣列相關演算法
問題1 列印1到最大的n位數 解法 一 直接求出n位數的最大值,然後直接從1開始列印 缺陷 可能會溢位,大數問題 void print1tomax int n for int i 1 icout cout 二 在字串上模擬數字加法 void print1tomax int n bool increm...
陣列相關演算法
1.尋找最小的k個數 有n個整數,請找出其中最小的k個數,要求時間複雜度盡可能低。全部排序。使用快速排序演算法排序之後並且輸出最小的k個數,時間複雜度為o nlogn def quick sort array,left,right if left right return low left high...
陣列相關問題總結
學習陣列或者使用陣列時總結的一些易忽略 不易懂 以及個人認為對自己重要的內容。push 在陣列的尾部新增乙個或者多個元素,並返回陣列新長度。pop 刪除陣列的最後乙個元素,減小陣列長度並返回它刪除的值。unshift 在陣列的頭部新增乙個或者多個元素,並返回陣列新長度。shift 刪除陣列的第乙個元...