演算法總結 陣列相關 陣列中找特定元素相關

2021-07-04 12:10:46 字數 2771 閱讀 7254

本次總結在陣列中查詢特定的元素。

碰到的面試題目主要包括:

題目的意思很明顯,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 刪除陣列的第乙個元...