1. 程式人生 > >做演算法題的幾個思路

做演算法題的幾個思路

演算法題目往往比較複雜,要麼讓人感到無從下手,要麼很難給出一個最優解,但這恰恰是考驗一個程式設計師思維方式的有效手段。看到這類的難題不要慌,《演算法設計與分析基礎》一書比較全面地總結了做演算法題目的一些思路:

(1)蠻力窮舉法,可以說可以解決所有的問題,不過對於組合數很大的問題時間效能不是很好甚至不能忍受。例子:全排列的生成、n選m組合的生成(這兩個的蠻力法都可以利用多重巢狀迴圈形成,層次很壯觀),8皇后問題(對應成8數全排列),12城tsp問題(對應成12數排列),a的n次方計算就老老實實連乘n次a,順序查詢元素等都是蠻力窮舉的例子。
(2)分治法,就是把1個大問題分成2個小問題,2個小問題還可以再分,直到問題規模小的可以簡單解決。處理每個小問題,把處理結果彙總處理,最後得到整個大問題的解。一般而言,分治法都要用到遞迴。例子:算n個數的和,可以算前一半n/2的和,後一半n/2的和,最後相加即得總和;凸包問題,可以把最左邊點和最右邊點連線,右上邊點集的凸包(叫做上包)和下面點集的凸包(叫做下包),最後把上包和下包合圍起來就是整個凸包。點集的最小點對問題,可以以一條線為界,分成左右兩個集合,分別求最小點對,最後在合起來處理。分治法對多個處理器或處理機的平行計算特別適用。
(3)減治法,就是處理過程中問題規模不斷減小的方法。最常見的就是折半查詢,每次都把n/2個元素刪去;減治法一半分為減1法,減常數法,減可變規模法。減1法典型的就是插入排序,還有計算a的n次方,可以計算a的n-1次方,再變成計算a的n-2次方等等。想查詢二叉樹的查詢都利用了減治的思想。
(4)變治法,就是對問題進行變相,變化,利用已有的解決方案來解決生疏的問題,重點在於對原來的生疏問題進行轉化,轉變,使他變成一個已有好的解法的熟悉問題。
(5)時空權衡,考慮時間和空間的相互轉化,有時利用空間換時間,有時利用時間換空間,常用的就是  計數排序(多利用了一個計數陣列),雜湊法,B樹。
(6)動態規劃,也是時空權衡的一種,把可重複的問題的解儲存在一個表裡面。例子包括   計算二項式係數,最有二叉查詢樹,揹包問題和記憶功能。
(7)貪婪演算法,就是每一步都從可選方案中選擇對該步最有利的方案,直到問題解決。貪婪法有可能得不到問題的最優解,不過得到的解一般都很接近問題的最優解。它的優點就是效率高,時間複雜性相對有那些得到最優解的演算法快很多。常用的例子:
最小生成樹的prim演算法,kruskal演算法,最短路徑的dijkstra演算法,解決tsp問題。
(8)回溯法
(9)分支限界法

相關推薦

演算法思路

演算法題目往往比較複雜,要麼讓人感到無從下手,要麼很難給出一個最優解,但這恰恰是考驗一個程式設計師思維方式的有效手段。看到這類的難題不要慌,《演算法設計與分析基礎》一書比較全面地總結了做演算法題目的一些思路: (1)蠻力窮舉法,可以說可以解決所有的問題,不過對於組合數很大的

資料結構演算法/兩字串的最長公共子序列

一,問題描述 給定兩個字串,求解這兩個字串的最長公共子序列(Longest Common Sequence)。比如字串1:BDCABA;字串2:ABCBDAB 則這兩個字串的最長公共子序列長度為4,最長公共子序列是:BCBA   二,演算法求解 這是一個動態規劃的題目。

資料結構演算法/兩有序陣列的中位數

有三種方法,時間複雜度分別是O(m+n) ,O(k),O(log(m+n)) 注意點: 判斷合併後的陣列的元素個數是奇數還是偶數 如果是奇數取中間值;如果是偶數取中間2個數的平均值。 兩種求中位數的方法: (1)方法1,判斷奇數個還是偶數個 if (lengthall % 2 == 0)

LeetCode演算法——兩排序陣列的中位數

4.給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2 。 請找出這兩個有序陣列的中位數。要求演算法的時間複雜度為 O(log (m+n)) 。 你可以假設 nums1 和 nums2 

圖靈機,Random Access Machine,和演算法基本要素

圖靈機 學過計算機課程的人,大概第一節課老師就會講圖靈,圖靈也被成為計算機之父。他是英國電腦科學家、數學家、邏輯學家、密碼分析學家和理論生物學家。他還提出了一種數學模型,圖靈機模型;圖靈機(Turing Machine,TM)又稱確定型圖靈機,它是一種抽象的計

LAMMPS降(升)溫的思路

模擬降溫,有大致兩種辦法,一個是連續(升)降溫,也就是dt間隔下不停的溫度下降(升);第二種方法是準靜態模擬降溫,每降低一個溫度,跑很長時間;這兩種方法大家可以根據自己情況進行模擬。 對於第一種方法,只需要進行fix nvt temp 1000 100 …的設定

cpu效能優化的思路

一:首先思考:(1)判斷是不是有效,優化後效能能提升多少  (2)有多個性能問題時,優先選擇哪一個 (3)有多個優化方法時,選擇哪一個,是不是用最大優化的那一個就可以了 二:優化前後的指標:應用程式方面(吞吐量和延遲),系統方面(cpu使用率等) cpu 優化:程式優化:編譯器優化,快取,非

論實現強人工智慧自然語言理解的思路 ---阮丁遠

        論實現強人工智慧自然語言理解的幾個思路Several ideas for achieving strong AI in natural language understanding 摘要:本文簡單說明了現有自然語言理解的不足,並給出了幾個思路來實現自然語

嘔心瀝血演算法——第一數字

// 以下的靜態方法實現了:把串s中第一個出現的數字的值返回。 // 如果找不到數字,返回-1 // 例如: // s = "abc24us43" 則返回2 // s = "82445adb5" 則返回8 // s = "ab" 則返回-1 function firstNum(str)

資料結構演算法/兩已排序陣列的交集和並集

兩個已排序陣列的交集和並集 問題: 給你兩個排序的陣列,求兩個陣列的交集。 比如: A = 1 3 4 5 7, B = 2 3 5 8 9, 那麼交集就是 3 5. 思路: 1. 每一次從B陣列中取一值,然後在A數組裡逐個比較,如果有相等的,則儲存。該演算法複雜度為 O(MN).

js演算法-Score of Parentheses

字母移位 題目描述: 給定一個平衡的括號字串S,根據以下規則計算字串的得分: ()有1分 AB有得分A + B,其中A和B是平衡的括號字串。 (A)有得分2 * A,其中A是一個平衡的括號字串。 例1: 輸入:"()" 輸出:1 例2:

粒子群演算法(6)-----適應度評價函式

下面給出幾個適應度評價函式,並給出圖形表示      頭幾天機子種了病毒,重新安裝了系統,不小心把程式全部格式化了,痛哭!!!沒辦法,好多程式不見了,現在把這幾個典型的函式重新編寫了,把他們給出來,就算粒子群演算法的一個結束吧!痛恨病毒!!!! 第一個函式:Griew

演算法-兩字串的最大公共子串

題目:給定一個query和一個text,均由小寫字母組成。要求在text中找出以同樣順序連續出現在query中最長連續字母序列的長度。例如,query為“acbac”,text為“acaccbabb”,那麼text中的“cba”為最長的連續出現在query中的字元序列,因此

演算法/第一只出現一次的字元

python2.7 在一個字串(1<=字串長度<=10000,全部由字母組成)中找到第一個只出現一次的字元,並返回它 思路:用set統計不同字元,並計算不同字元出現的次數,如果某個字元出現次數是1,就返回。 class Solution:

演算法經典遞推關係記錄

遞推關係數學味很重(貌似很多都是直接有公式的),不過很多記憶搜尋或者dp的狀態轉移都是要自己推理的,記錄幾個俗爆炸的遞推關係... 文科生學計算機......我呵呵一臉 :( Fibonacci 這個很常見,第一次刷題愣是沒找出來...覺得特難(文科生的悲哀)! 目前

兩道有趣的演算法(只有思路

1、一條長l的筆直的街道上有n個路燈,若這條街的起點為0,終點為l,第i個路燈座標為ai,每盞燈可以覆蓋到的最遠距離為d,為了照明需求,所有燈的燈光必須覆蓋整條街,但是為了省電,要是這個d最小,請找到

程式設計師練習演算法實用技巧

上週在公司內部分享了自己練習演算法的心得和經驗,有小夥伴表示分享的內容給他帶來了價值,也很具備參考意義,於是就演算法寫成文章分享出來,近幾個月來,自己每週都會花1、2小時在 Leetcode 上面練習演算法,短短几個月下來也陸陸續續交出 40~50 的解題作業,算是一個小小的里程碑吧,以下是我最近的刷題記錄:

6關於Java包裝類拆箱和裝箱的判斷,你能

雖然 Java 語言是典型的面向物件程式語言,但其中的八種基本資料型別並不支援面向物件程式設計,基本型別的資料不具備“物件”的特性——不攜帶屬性、沒有方法可呼叫。為此,Java為每種基本資料型別分別設計了對應的類,稱之為包裝類(Wrapper Classes)。 裝箱(Box

有名的線上系統(ACM OJ)

1. 浙江大學 Online Judge(ZOJ) http://acm.zju.edu.cn      國內最早也是最有名氣的OJ,有很多高手在上面做題。特點是資料比較刁鑽,經常會有你想不到的邊界資料,很能考驗思維的全面性。 2. 北京大學 Online Judge(P

有意思的演算法(高斯日記、排它平方數、振興中華、顛倒的價牌)

    大數學家高斯有個好習慣:無論如何都要記日記。     他的日記有個與眾不同的地方,他從不註明年月日,而是用一個整數代替,比如:4210     後來人們知道,那個整數就是日期,它表示那一天是高斯出生後的第幾天。這或許也是個好習慣,它時時刻刻提醒著主人:日子又過去一天,還有多少時光可以用於浪費呢