一些雜七雜八的演算法(打表,遞推,隨機選擇演算法)

2021-09-25 21:19:17 字數 1728 閱讀 4787

打表

打表是一種以空間換時間的策略,下面舉幾個打表的形式。

1 在程式中一次性計算出所有結果,之後的查詢直接採用這些結果。

2 在另乙個程式中暴力計算出結果,再把程式存到陣列裡,直接使用。相當於暴力演算法。

3 先暴力計算小範圍資料的結果,然後根據規律找出解決問題的方法。

遞推如果題目中有遞推關係的話,活用遞推關係就可以降低時間複雜度。

例如,對於序列問題來說,假如序列中的每一位所需要計算的值都可以通過左右兩側的結果計算得到,那麼就可以考慮左右兩側的結果能否通過遞推得到,這樣就能避免反覆計算,從而降低時間複雜度。

下面來看一道題:

pat b1040 有幾個pat

現給定字串,問一共可以形成多少個 pat?

輸入格式:

輸入只有一行,包含乙個字串,長度不超過10​5,只包含 p、a、t 三種字母。

輸出格式:

在一行中輸出給定字串中包含多少個 pat。由於結果可能比較大,只輸出對 1000000007 取餘數的結果。

我們先來看一下思路。最容易想到的辦法就是暴力,但是會超時。但如果我們換個角度思考問題,對於每乙個a,以它形成的pat個數等於它左邊的p的個數乘以它右邊的t的個數。於是問題就轉變為,對字串中的每個a,計算它左邊p的個數與右邊t的個數的乘機,再把所有a的結果相加即可。

首先要獲得所有左邊p的個數。這裡有乙個方法,開乙個陣列leftp,然後如果當前位i的元素是p,那麼leftp[i]等於leftp[i-1]+1,否則leftp[i]就等於leftp[i-1],這樣這個陣列就能記錄每個位置,它左邊的p的個數。

然後再考慮右邊t的個數,從序列右邊開始遍歷,是t則用計數器記下來,遇到不是t且是a的時候,就查閱a左邊的位置的leftp的值,然後再乘以計數器裡的t。最後累加即可(記得取模)

**如下:

#include

using namespace std;

const

int maxn =

100010

;const

int mod =

1000000007

;char str[maxn]

;int leftp[maxn]=;

intmain()

if(str[i]

=='p')}

for(i = len-

1; i >=

0; i--)}

printf

("%d"

,ans)

;return0;

}

隨機選擇演算法

先看這樣乙個問題:如何從乙個無序的、沒有相同元素的陣列中找出第k大的數。

舉個例子,對於陣列來說,5就是第5大的數。

最直接的演算法是對陣列排序然後選出第k大的元素,但這樣做的時間複雜度是o(nlogn),而我們有更優解,可以讓時間複雜度變為o(n)。

隨機選擇演算法類似於隨機快排演算法。對於乙個陣列a,在[left,right]區間內應用該演算法,則先利用randpartition(在我部落格two pointers裡有講解到這個函式)選出乙個位置p,那麼a[p]左邊全是比a[p]小的元素,則a[p]是該序列第p-left+1大的元素,不妨令m=p-left+1,如果k=m,那麼a[p]即為結果;如果kint

randselect

(int a,

int left,

int right,

int k)

else

}隨機選擇演算法的時間複雜度是o(n)。

一些雜七雜八的總結

script var url console.log encodeuricomponent url 編碼 var after encodeuricomponent url console.log decodeuricomponent afterurl 解碼 script indexof 字元 根據字...

雜七雜八 的一些記錄

算一下,來公司實習打卡已經38天了 正式打卡領工資的天數 但是從第一天來公司19年11月14號,已經3個月左右了.現在坐在工位上,有點.迷茫.感覺自己.不夠主動的溝通啊,這件事其實不難,難的時候就覺得好難.總覺得自己能夠更加高效率一點,但也只是總覺得,事實就是自己每天做的事情很少。想起剛進公司第一天...

一些雜七雜八的前端相關

1 最近閉關 封閉式開發 模仿nodejs造的乙個和url相關的小模組,配合做個分頁元件很不錯 1 獲取引數 var id iurls.query.id或var id iurls.param id 2 設定引數 返回location.search iurls.setparam name,value ...