漫遊演算法 01 認識演算法

2021-08-11 23:20:32 字數 2357 閱讀 2654

我是一名初中oier。在開始寫這第一篇文章之前,我其實已經反覆考慮很久了。起初我不敢冒然寫。一是由於我的程式設計水平不是特別精湛,沒有積累足夠的經驗;二是我的語文比較弱,寫出的文章可能並不精彩,甚至難以理解。

但是我最終決定開始部落格生涯,因為我相信寫文章是每個oier都不得不經歷的。寫文章不僅僅可以幫助其他人,還能提高自身的程式設計以及語文水平。希望我能通過寫文章,分享自己現有的經驗,同時通過他人的評價得到一些新的感悟。

想要漫遊演算法,首先,要對演算法有正確的認識。

演算法,你絕對不會陌生,本質上它就是解決問題所用的方法。同乙個問題,自然會有多種不同的演算法。那麼,我們先從乙個經典的算式引入演算法的概念,同時將演算法推廣到程式設計。

小學低年級的你我,碰到這題,第一反應也許是驚詫,若硬是要算出答案,只好在草稿紙上手動乙個乙個加起來,結果半天時間,豎式列滿了整頁草稿紙,終於計算出了正確的答案。

到了高年級,才發現當時自己的方法是如此死板!根據加法交換和結合律,可以合併 1 和 100 為乙個 101,2 和 99 剛好也可以合併成乙個 101,3 和 98,4 和 97,以此類推……最終推算出相鄰的 50 和 51 可以合併成最後乙個 101,1 到 50 有 50 個整數,也就是合併了 50 個 101,50 乘 101 等於 5050,所以原算式的答案就是 5050,問題完美解決……

想當年數學王子高斯,發現了這種方法,方才受到重視。由此可見,演算法作為解決問題的方法,是百變莫測、滿具魅力的。

若我們將上面經典的算式交給一位幼兒園的小盆友計算,他認識數字卻不會任何加法,於是始終得不到答案,這也屬於一種演算法嗎?

不,演算法擁有一條很重要的性質。任何演算法允許沒有指定的前提,但必須要有肯定而正確的結果。不論多麼絞盡腦汁,沒有正確的答案,這解題方法就不屬於正確的演算法。

當然,有時候我們將問題複雜化,得到正確但費時的演算法。例如,還是那個算式,我們使用以下的演算法:找遍整個式子,統計式子裡有多少個 1,很顯然只有 1 個,所以心中的答案加上 1;繼續找遍整個式子,統計式子裡有多少個 2,仍然只有 1 個,所以心中的答案再加上 2……直到被統計的數到 100 為止。上面的演算法,可以得到正確答案 5050,但比直接乙個乙個加起來這種演算法還要慢。

因此,即使同乙個問題有多種演算法,但每種演算法畢竟存在自身的優劣性,需要我們的探尋與選擇。

現在我們將演算法的概念推廣到程式設計中。這時,我們引入「複雜度」來評價演算法的優劣。程式設計中,它一般分為「時間複雜度」「空間複雜度」。要知道,即使是計算機,運算速度極快,也有自己的限度。時間複雜度特別大的演算法,代入程式執行也需要一段時間。同時,空間複雜度也不能過大,計算機的儲存空間大但依然是有限的。解一道題,使用的演算法,時間複雜度和空間複雜度都盡量要保持在乙個限度內。

複雜度使用 θ(

...)

來表示,通常簡寫為 o(

...)

。括號內一般填寫代數式,若代數式內有變數,則複雜度會隨著變數的變化而變化,此時常數項通常省略。例如 o(

m2+n

logn

) ,其中 lo

g 一般表示底數為 2 的對數運算。有時,複雜度僅會保留乙個次數最高的項。若沒有變數,整個複雜度都僅僅是常數,一般表示為 o(

1)。

下面,我們再使用乙個式子作為例子。

如果我們要設計乙個程式,實現:輸入正整數

n (可能很大),輸出該算式的結果。

最容易想到的演算法,即使用單層迴圈從 1 到

n統計入乙個總和變數。考慮到使用了乙個迴圈,如果

n 很大,迴圈次數也會跟著很大。因此時間複雜度不難看出是 o(

n)。至於空間複雜度,整個過程都無需使用陣列,僅需要少量的變數即可完成,所以空間複雜度為常數複雜度,即 o(

1)。

更加優秀的演算法,即高斯的思想,只需要分析後碼上一些式子就同樣能求出正解,連迴圈都不需要,時空複雜度皆為 o(

1)。

更加費時的演算法,上面也講到過了。列舉要找的數,再找遍整個式子,統計,加入答案。列舉就要一層迴圈,找遍整個式子更不用說了。時間複雜度是 o(

n2) ,空間複雜度看情況而定。

如果 n

=100

,似乎三個演算法複雜度的差異並不大,跑得都比較快。然而當 n=

109呢?此時差距將異常明顯,演算法的優劣性也得以展現。解決一道程式設計問題,我們應該學會估算時空複雜度。

人是活的,演算法也是活的。演算法的路永遠也走不完,所以在學習演算法的同時,我們也應探尋更加優秀的演算法。

01 認識演算法

資料結構是指相互之間存在的一種或多種特定關係的資料元素集合。資料型別按結構特徵劃分 五大特性 資料結構是有限的,只有寥寥數種,而演算法則是琳琅滿目的。資料結構就彷彿乙個蘋果,演算法則是你選擇吃蘋果的方式。function sum n return total 上面是乙個累加求和的方法,假設每條語句執...

認識回溯演算法

目錄原理 相似演算法 實現 提高效率的技巧 使用場景 經典回溯演算法案例 回溯演算法思想有點像時空穿越,就是每次面對選擇時從一組可能的解中,選擇乙個滿足要求的解,如果當你發現選錯了的時候,就穿越時空回到上乙個時間點重新選擇。回溯演算法本質上就是列舉,列舉所有的解,找到符合的解。貪心演算法 每次面對選...

認識 LFU 演算法

目錄 1 leetcode460.lfu快取 2 思路分析 3 實現 3.1 get 方法 3.2 put 方法 3.3 increasefreq方法 核心 3.4 removeminfreq方法 核心 3.5 完整 請你為 最不經常使用 lfu 快取演算法設計並實現資料結構。它應該支援以下操作 g...