一些常用的演算法技巧

2021-09-11 09:08:11 字數 2758 閱讀 6561

1、巧用陣列下標

例:在統計乙個字串中字幕出現的次數時,我們就可以把這些字母當做陣列下標,在遍歷的時候,如果字母a遍歷到,則arr['a']就可以加1了。

法一:利用物件的key值不重複

var str = 'hajshdjldjf';

function count(str);

for(var i = 0; i < str.length; i++)else

}console.log(obj);

return obj;

}count(str);複製**

法二:利用陣列的下標

var str = 'hajshdjldjf';

function count(str)else

}}count(str);複製**

其實這兩種方法的思想是一致的。

例:給你n個無序的int整型陣列arr,並且這些整數的取值範圍都在0-20之間,要你在 o(n) 的時間複雜度中把這 n 個數按照從小到大的順序列印出來。

對於這道題,如果你是先把這 n 個數先排序,再列印,是不可能o(n)的時間列印出來的。但是數值範圍在 0-20。我們就可以巧用陣列下標了。把對應的數值作為陣列下標,如果這個數出現過,則對應的陣列加1。

利用物件:

var arr = [1,2,3,4,5,4,5,6,6,7,6,9,17,16,15,14,12,11];

//常規解法 利用物件的key值不能重複去計算次數

//res去記錄數字出現的順序

function fn(arr));

var res = ;

var resdetail = ;

for(var i = 0; i < arr.length; i++);

resdetail.push(obj);

}else

}console.log(resdetail);

return resdetail;

}fn(arr);複製**

利用陣列下標

var arr = [1,2,3,4,5,4,5,6,6,7,6,9,17,16,15,14,12,11];

//利用陣列下標 時間複雜度為o(n)

function fn(arr)

for(var j = 0; j < 21; j++)

}}fn(arr);複製**

2、巧用取餘

有時候我們在遍歷陣列的時候,會進行越界判斷,如果下標差不多要越界了,我們就把它置為0重新遍歷。特別是在一些環形的陣列中,例如用陣列實現的佇列。往往會寫出這樣的**:

for (int i = 0; i < n; i++)

pos++;

}}複製**

實際上我們可以通過取餘的方法來簡化**

for (int i = 0; i < n; i++) 複製**
3、巧用雙指標

對於雙指標,在做關於單鏈表的題是特別有用,比如「判斷單鏈表是否有環」、「如何一次遍歷就找到鍊錶中間位置節點」、「單鏈表中倒數第 k 個節點」等問題。對於這種問題,我們就可以使用雙指標了,會方便很多。

(1)判斷單鏈表中是否有環

我們可以設定乙個快指標和乙個慢指標,慢的一次移動乙個節點,快的一次移動兩個節點。如果存在環,快指標會在第二次遍歷時和慢指標相遇。

(2)如何一次遍歷就找到鍊錶中間位置節點

一樣是設定乙個快指標和慢指標。慢的一次移動乙個節點,快的一次移動兩個。當快指標遍歷完成時,慢指標剛好到達中點。

(3)單鏈表中倒數第 k 個節點

設定兩個指標,其中乙個指標先移動k-1步,從第k步開始,兩個指標以相同的速度移動。當那個先移動的指標遍歷完成時,第二個指標指向的位置即倒數第k個位置。

4、巧用位移

有時候我們在進行除數或乘數運算的時候,例如n / 2,n / 4, n / 8這些運算的時候,我們就可以用移位的方法來運算了,這樣會快很多。

例如:n / 2 等價於 n >> 1

n / 4 等價於 n >> 2

n / 8 等價於 n >> 3。

這樣通過移位的運算在執行速度上是會比較快的,也可以顯的你很厲害的樣子,哈哈。

還有一些 &(與)、|(或)的運算,也可以加快運算的速度。例如判斷乙個數是否是奇數,你可能會這樣做

if(n % 2 == 1)複製**

不過我們用與或運算的話會快很多。例如判斷是否是奇數,我們就可以把n和1相與了,如果結果為1,則是奇數,否則就不會。即

if(n & 1 == 1)else

}console.log(fn(10));複製**

不過對於可以使用遞迴解決的問題,我們一定要考慮是否有很多重複計算。顯然對於 f(n) = f(n-1) + f(n-2) 的遞迴,是有很多重複計算的。如

就有很多重複計算了。這個時候我們要考慮狀態儲存。並且可以自底向上。

function fn(n)

console.log(res[n-1]);

return res[n-1];

}fn(10);複製**

進一步優化:使用兩個變數。

function fn(n)

return a;

}fn(10);複製**

一些常用的演算法技巧總結

一些常用的演算法技巧總結 給定兩個字串 s 和 t 編寫乙個函式來判斷 t 是否是 s 的字母異位詞。示例 1 輸入 s anagram t nagaram 輸出 true 示例 2 輸入 s rat t car 輸出 false 說明 你可以假設字串只包含小寫字母。public boolean i...

VIM 一些常用技巧

多行增加指定字元 進入vi vim編輯器,按ctrl v進入視覺化模式 visual block 移動游標上移或者下移,選中多行的開頭 選擇完畢後,按大寫的的i鍵,此時下方會提示進入 insert 模式,輸入你要插入的注釋符,例如 最後按esc鍵,你就會發現多行 已經被注釋了 刪除多行 ctrl v...

Processing一些常用技巧

一些常用技巧總結 tweak模式是非常有用的功能,自3.0版本後,它就正式整合到processing中。程式中影象元素的大小 比例 角度等,都由具體的引數控制。要使畫面更具美感,單用 來確定結構是遠遠不夠的,調參同樣重要。在沒有tweak模式誕生前,要調出乙個讓人滿意的效果,需要反覆開啟程式來觀察結...