常見演算法題

2021-06-18 08:35:33 字數 3028 閱讀 9555

一、維護o(1)時間查詢最大元素的棧

問題描述:乙個棧stack,具有push和pop操作,其時間複雜度皆為o(1)。設計演算法max操作,

求棧中的最大值,該操作的時間複雜度也要求為o(1)。

可以修改棧的儲存方式,push,pop的操作,但是要保證o(1)的時間複雜度,空間時間複雜

度無要求。

可以建立乙個類,類裡有兩個棧,乙個棧s維持正常的push、pop操作,另乙個sm儲存當前的最大值

假設元素以5,4,1,2,3,10,9,8,6,7,15順序入棧,則兩個棧中儲存的元素如下圖所示:

s    5    4    1    2    3    10    9    8    6    7    15

sm 5    10  15

struct max_stack;

max_stack s;

void my_push(int k) else

}void my_pop()

}int my_max()

}

二、約瑟夫環問題

瑟夫環問題的原來描述為,設有編號為1,2,……,n的n(n>0)個人圍成乙個圈,從第1個人

開始報數,報到m時停止報數,報m的人出圈,再從他的下乙個人起重新報數,報到m時停止

報數,報m的出圈,……,如此下去,直到所有人全部出圈為止。當任意給定n和m後,設計

演算法求n個人出圈的次序。換一種表述如下

問題描述:n個人(編號0~(n-1)),從0開始報數,報到(m-1)的退出,剩下的人繼續從0開始

報數。求勝利者的編號。

具體數學上給出通項公式:

f(0)=0       

f(n)=(f(n-1)+m)%n    ,    (n>1)

int joseph(int n,int m) 

return a[0];

}

由於詢問和交換的時間複雜度是o(1),while迴圈進行了n-1次,所以時間複雜度是o(n).

四、最小交流次數

問題描述:有n個戰士其中n>4他們手中都有不同的情報,假設每個人通過交流能過得雙方所有

的情報。設計乙個演算法使得用最少的交流次數使得所有的戰士都獲得全部的情報,給出演算法並

給出最小交流次數?

可以建立遞推式:

f(4)=4

f(n)=f(n-1)+2  ,  n>4

假設在戰士人數是n-1時需要f(n-1)次交流,則增加乙個人時,如下步驟進行:

1、第n個戰士和前面任意乙個戰士交流一次

2、前n-1個戰士互相交流,使得前面n-1個戰士都有所有戰士獲得的情報

3、第n個戰士和前面任意乙個戰士交流一次。

這樣n個戰士都有所有情報了。

五、數星星

問題描述:a和b晚上無聊就開始數星星。每次只能數k個(20<=k<=30)a和b輪流數。最後

誰把星星數完誰就獲勝,那麼當星星數量為多少時候a必勝?

這是乙個博弈的問題,我們可以從勝利條件出發,a必勝,那麼最後一次是a數,並且剩下星星

的個數 20<=k<=30 ,那麼如何保證呢?最後50顆由b先數,b數m顆,然後a數剩下的50-m

顆。好了,那麼第一次a數的話必須保證,第一次a數完之後,剩下的個數是50的倍數。所以

案就明了了,星星的數量應滿足    

50k+20 <= n <=50k+30    ,    k是整數

六、求連續子陣列的最大和

這是乙個動態規劃問題遞推式為

m(i)=max,i>0

int max_sub_sum(int *a,int n) 

return maxsum;

}

七、二分查詢

用二分法查詢已排序的大小為n的陣列a是否存在value,如果存在返回下標,否則返回-1。

int b_search(int *a,int n,int value) 

return -1;

}

**:
八、分糖果
有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳

遞乙個糖果代價為1,求使所有人獲得均等糖果的最小代價。設xi為第i-1個小朋友分給第i個小朋友的糖果數,g為最後的平均數。其中x1為第n個小朋友分給第1個小朋友的糖果數。

a1 +x1 + x2 = g

a2 + x2 - x3 = g

.an + xn - x1 = g

解得x1 = x1

x2 = a1 - g - x1

x3 = a1 + a2 - g - g + x1

.xn = a(n-1)+a(n-2)+...a2+a1 - (n -1)* g + x1

則總開銷為:|x1|+|x2|+...+|xn| =|x1|+ |a1-g+x1| + |a2+a1-2*g+x1| + ... +|a(n-1)+a(n-2)+...a2+a1 - (n -1)* g + x1|

設s[i]=ai+ ... +a1- i*g; 則上式=|x1| + ∑|s[i]+x1|    ,1=< i<=n-1

設k為第乙個分給第n個的數量為k,則k=-x1,上式為:|k| + ∑|s[i]-k| ,1=< i<=n-1

要使上式值最小,則k為0, s[1], s[2], ......s[n-1]的中位數。

這主要是利用了中位數的乙個性質:陣列中數與中位數差的絕對值和最小。

1 #include 2 #include 3 #include 4

using

namespace std;

5const

long

long n = 2001000;

6long

long a[n], s[n], tar[n], n;

7int main ()

8

**:

演算法 常見演算法題

演算法題 假如有100個不相同的數,比如從1到100,怎樣使用10次取出其中的10個不同的數字,要求每個數取出的概率一樣 一開始沒有說10次,所以我說,使用乙個random函式,以時間為種子來取,當取出乙個時,做標記,下次再取到這個數時,重新取一次 然後他就說了如果只能夠取10次怎麼辦?一開始我想到...

常見演算法題

1.用簡單素數篩選法求n以內的素數。void printprime 2.使用位操作壓縮後的篩素數方法 include include int getprime int primes,int max 4.給定乙個包含n個整數的陣列,除了乙個數出現一次外,所有整數均出現三次,找出這個只出現一次的整數.思...

常見js演算法題

author laifeipeng date 2019 02 21 17 50 13 last modified by laifeipeng last modified time 2019 02 21 18 12 27 1 判斷回文字串 法一 function palindrome str retu...