2糠涛、常見基礎(chǔ)算法原理

1、貪心算法

貪心算法的指導(dǎo)思想是:每一步下的最優(yōu)兼犯,也就是局部最優(yōu)忍捡,一定情況下逼近全局最優(yōu)集漾。

對應(yīng)刷題:買賣股票的最佳時機

(1)給定一個數(shù)組,它的第?i 個元素是一支給定股票第 i 天的價格砸脊。

設(shè)計一個算法來計算你所能獲取的最大利潤具篇。你可以盡可能地完成更多的交易(多次買賣一支股票)。

class?Solution:

????def?maxProfit(self,?prices:?List[int])?->?int:

????????#貪心算法

????????max1=0

????????k=len(prices)

????????for?i?in?range(1,k):

????????????max1=max1+max((prices[i]-prices[i-1]),0)

????????return?max1

(2)給定一個數(shù)組凌埂,它的第?i 個元素是一支給定股票第 i 天的價格栽连。

如果你最多只允許完成一筆交易(即買入和賣出一支股票一次),設(shè)計一個算法來計算你所能獲取的最大利潤侨舆。

class?Solution:

????def?maxProfit(self,?prices:?List[int])?->?int:

? ? ? ?if?len(prices)<=1:

????????????return?0

???????else:

????????result=0

????????min1=prices[0]

????????for?i?in?range(1,len(prices)):

????????????if?prices[i]<min1:

????????????????min1=prices[i]

????????????result=max(result,prices[i]-min1)

????????return?result

(3)中等 跳躍游戲

給定一個非負(fù)整數(shù)數(shù)組秒紧,你最初位于數(shù)組的第一個位置。

數(shù)組中的每個元素代表你在該位置可以跳躍的最大長度挨下。

判斷你是否能夠到達最后一個位置熔恢。

class?Solution:

????def?canJump(self,?nums:?List[int])?->?bool:

????????mostright=0

????????for?i?in?range(len(nums)):

???????????????if?i<=mostright:

???????????????????mostright=max(mostright,i+nums[i])

???????????????????if?mostright>=len(nums)-1:

???????????????????????return?True

????????return?False

2、動態(tài)規(guī)劃

用一句話解釋動態(tài)規(guī)劃就是 “記住你之前做過的事”臭笆,如果更準(zhǔn)確些叙淌,其實是 “記住你之前得到的答案”。

動態(tài)規(guī)劃解題四個步驟:

問題拆解愁铺,找到問題之間的具體聯(lián)系

狀態(tài)定義

遞推方程推導(dǎo)

實現(xiàn)(初始化)

典型例題1:爬樓梯LeetCode 第 70 號問題:爬樓梯鹰霍。

假設(shè)你正在爬樓梯。需要?n階你才能到達樓頂茵乱。

每次你可以爬 1 或 2 個臺階茂洒。你有多少種不同的方法可以爬到樓頂呢?

時間優(yōu)瓶竭,空間不優(yōu)督勺。

class?Solution:

????def?climbStairs(self,?n:?int)?->?int:

????????reslut=[]

????????reslut.append(1)

????????reslut.append(2)

????????for?i?in?range(2,n):

?????????????reslut.append(reslut[i-1]+reslut[i-2])

????????return?reslut[n-1]

典型例題2:LeetCode 第 53 號問題:最大子序和。

給定一個整數(shù)數(shù)組?nums?斤贰,找到一個具有最大和的連續(xù)子數(shù)組(子數(shù)組最少包含一個元素)智哀,返回其最大和。

class?Solution:

????def?maxSubArray(self,?nums:?List[int])?->?int:

????????smax=nums[0]

????????tmp=nums[0]

????????for?i?in?range(1,len(nums)):

????????????tmp=max(tmp,0)

????????????smax=max(nums[i]+tmp,smax)

????????????tmp=tmp+nums[i]

????????return?smax

典型例題3:

你是一個專業(yè)的小偷荧恍,計劃偷竊沿街的房屋瓷叫。每間房內(nèi)都藏有一定的現(xiàn)金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統(tǒng)送巡,如果兩間相鄰的房屋在同一晚上被小偷闖入摹菠,系統(tǒng)會自動報警。

給定一個代表每個房屋存放金額的非負(fù)整數(shù)數(shù)組授艰,計算你 不觸動警報裝置的情況下 辨嗽,一夜之內(nèi)能夠偷竊到的最高金額世落。

class?Solution:

????def?rob(self,?nums:?List[int])?->?int:

???????if?len(nums)==0:

????????????return?0

???????else:

????????if?len(nums)<=2:

????????????return?max(nums)

????????else:

????????????first=nums[0]

????????????second=max(nums[0],nums[1])

????????????for?i?in?range(2,len(nums)):

????????????????nums[i]=max(first+nums[i],second)

????????????????first=second

????????????????second=max(first,nums[i])

????????????return?nums[len(nums)-1]

通過這幾個簡單的例子淮腾,相信你不難發(fā)現(xiàn)糟需,解動態(tài)規(guī)劃題目其實就是拆解問題,定義狀態(tài)的過程谷朝,嚴(yán)格說來洲押,動態(tài)規(guī)劃并不是一個具體的算法,而是凌駕于算法之上的一種 思想 圆凰。

這種思想強調(diào)的是從局部最優(yōu)解通過一定的策略推得全局最優(yōu)解杈帐,從子問題的答案一步步推出整個問題的答案,并且利用空間換取時間专钉。從很多算法之中你都可以看到動態(tài)規(guī)劃的影子挑童,所以,還是那句話 技術(shù)都是相通的跃须,找到背后的本質(zhì)思想是關(guān)鍵站叼。

參考網(wǎng)址:https://www.cxyxiaowu.com/6781.html

3、分治思想

分治策略:對于一個規(guī)模為 n 的問題菇民,將其分解為 k 個規(guī)模較小的子問題尽楔,這些子問題互相獨立且與原問題形式相同,遞歸地解這些子問題第练,然后將各子問題的解合并得到原問題的解阔馋。

關(guān)鍵點:遞歸地解子問題,合并得到原問題的解娇掏,歸并排序的典型思路呕寝。

典型例題1:二分查找。

x 的平方根:實現(xiàn)?int sqrt(int x)?函數(shù)婴梧。計算并返回?x?的平方根壁涎,其中?x 是非負(fù)整數(shù)。由于返回類型是整數(shù)志秃,結(jié)果只保留整數(shù)的部分怔球,小數(shù)部分將被舍去。

class?Solution:

????def?mySqrt(self,?x:?int)?->?int:

????????????????l=0

????????????????r=x

????????????????ans=-1

????????????????while?l<=r:

????????????????????m=int((l+r)/2)

????????????????????if?m*m<=x:

????????????????????????ans=m

????????????????????????l=m+1

????????????????????else:

????????????????????????r=m-1

????????????????return?ans

典型例題2:歸并排序浮还。

歸并排序竟坛,兩路已經(jīng)有序,合并成一路钧舌,關(guān)鍵點:如果兩個數(shù)組是有序的担汤,則可以便捷地計算兩個數(shù)組的交集。

首先對兩個數(shù)組進行排序洼冻,然后使用兩個指針遍歷兩個數(shù)組崭歧。

初始時,兩個指針分別指向兩個數(shù)組的頭部撞牢。每次比較兩個指針指向的兩個數(shù)組中的數(shù)字率碾,如果兩個數(shù)字不相等叔营,則將指向較小數(shù)字的指針右移一位,如果兩個數(shù)字相等所宰,將該數(shù)字添加到答案绒尊,并將兩個指針都右移一位。當(dāng)至少有一個指針超出數(shù)組范圍時仔粥,遍歷結(jié)束婴谱。

給定兩個數(shù)組,編寫一個函數(shù)來計算它們的交集躯泰。

classSolution: defintersect(self, nums1: List[int], nums2: List[int])-> List[int]: nums1.sort()

? ? ? ? nums2.sort()

? ? ? ? result=[]

? ? ? ? length1=len(nums1)

? ? ? ? length2=len(nums2)

? ? ? ? index1=0? ? ? ? index2=0? ? ? ? while index1<length1 and index2<length2:

? ? ? ? ? ? if nums1[index1]<nums2[index2]:

? ? ? ? ? ? ? ? index1=index1+1? ? ? ? ? ??

? ? ? ? ? ? elif nums1[index1]>nums2[index2]:

? ? ? ? ? ? ? ? ? index2=index2+1? ? ? ? ? ??

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? ? result.append(nums1[index1])

? ? ? ? ? ? ? ? ? index1=index1+1? ? ? ? ? ? ? ? ??

? ? ? ? ? ? ? ? ? ?index2=index2+1? ? ? ??

? ? ? ? ? return result

歸并排序:歸并(Merge)排序法是將兩個(或兩個以上)有序表合并成一個新的有序表谭羔,即把待排序序列分為若干個子序列,每個子序列是有序的麦向。然后再把有序子序列合并為整體有序序列口糕。即先劃分為兩個部分,最后進行合并磕蛇。

典型例題3:977. 有序數(shù)組的平方

給定一個按非遞減順序排序的整數(shù)數(shù)組?A景描,返回每個數(shù)字的平方組成的新數(shù)組,要求也按非遞減順序排序秀撇。

low一點的版本:

class?Solution:

????def?sortedSquares(self,?A:?List[int])?->?List[int]:

????????length=len(A)

????????if?length==0:

????????????return?A

????????else:

????????????result=[]

????????????l=0

????????????r=length-1

????????????while?l<=r:

????????????????tmp1=A[l]*A[l]

????????????????tmp2=A[r]*A[r]

????????????????if?tmp1<tmp2:

????????????????????result.insert(0,tmp2)

????????????????????r=r-1

????????????????elif?tmp1>tmp2:

????????????????????result.insert(0,tmp1)

????????????????????l=l+1

????????????????else:

????????????????????result.insert(0,tmp1)

????????????????????if?l!=r:

???????????????????????result.insert(0,tmp2)

????????????????????l=l+1

????????????????????r=r-1

????????return??result

優(yōu)化后的版本:

class?Solution:

????def?sortedSquares(self,?A:?List[int])?->?List[int]:

????????length=len(A)

????????if?length==0:

????????????return?A

????????else:

????????????result=[]

????????????l=0

????????????r=length-1

????????????while?l<=r:

????????????????tmp1=A[l]*A[l]

????????????????tmp2=A[r]*A[r]

????????????????if?tmp1<tmp2:

????????????????????result.insert(0,tmp2)

????????????????????r=r-1

????????????????else:

????????????????????result.insert(0,tmp1)

????????????????????l=l+1

????????return??result

典型例題3:快速排序超棺。

快速排序的基本思想:當(dāng)前待排序的無序區(qū)為 A[low..high] ,利用分治法可將快速排序的基本思想描述為:

(1)分解:

在A[low..high]中任選一個記錄作為基準(zhǔn)(pivot)呵燕,以此基準(zhǔn)將當(dāng)前無序區(qū)劃分為左棠绘、右兩個較小的子區(qū)間R[low..pivotpos-1) 和 R[pivotpos+1..high] ,并使左邊子區(qū)間中所有記錄的關(guān)鍵字均小于等于基準(zhǔn)記錄(不妨記為pivot)的關(guān)鍵字 pivot.key再扭,右邊的子區(qū)間中所有記錄的關(guān)鍵字均大于等于pivot.key氧苍,而基準(zhǔn)記錄pivot則位于正確的位置( pivotpos )上,它無須參加后續(xù)的排序泛范。

(2)求解:

通過遞歸調(diào)用快速排序?qū)ψ笕门啊⒂易訁^(qū)間R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。

(3)合并:

因為當(dāng)"求解"步驟中的兩個遞歸調(diào)用結(jié)束時罢荡,其左赡突、右兩個子區(qū)間已有序。對快速排序而言区赵,"組合"步驟無須做什么惭缰,可看作是空操作。

總結(jié)分析:

分治法將規(guī)模為 n 的問題分成 k 個規(guī)模為 n/m 的子問題去解笼才。設(shè)分解閥值 n0 = 1 漱受,且 adhoc 解規(guī)模為 1 的問題耗費 1 個單位時間。再設(shè)將原問題分解為 k 個子問題以及用 merge 將 k 個子問題的解合并為原問題的解需用 f(n) 個單位時間骡送。用T(n)表示該分治法解規(guī)模為 |P| = n 的問題所需的計算時間昂羡,則有:

??T(n)= k T(n/m) + f(n)

4絮记、遞歸算法

先下定義:遞歸算法是一種直接或者間接調(diào)用自身函數(shù)或者方法的算法。

通俗來說紧憾,遞歸算法的實質(zhì)是把問題分解成規(guī)牡角В縮小的同類問題的子問題昌渤,然后遞歸調(diào)用方法來表示問題的解赴穗。它有如下特點:

1. 一個問題的解可以分解為幾個子問題的解

2. 這個問題與分解之后的子問題,除了數(shù)據(jù)規(guī)模不同膀息,求解思路完全一樣

3. 存在遞歸終止條件般眉,即必須有一個明確的遞歸結(jié)束條件,稱之為遞歸出口潜支。

典型例題1:漢諾塔問題


5甸赃、回溯算法



待補充:

查找算法

排序算法

搜索算法

字符串匹配算法

接下來是各種數(shù)據(jù)結(jié)構(gòu):

線性表、散列表冗酿、樹埠对、圖


參考資料:

內(nèi)容來自:https://zhuanlan.zhihu.com/p/137041568

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市裁替,隨后出現(xiàn)的幾起案子项玛,更是在濱河造成了極大的恐慌,老刑警劉巖弱判,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件襟沮,死亡現(xiàn)場離奇詭異,居然都是意外死亡昌腰,警方通過查閱死者的電腦和手機开伏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遭商,“玉大人固灵,你說我怎么就攤上這事〗倭鳎” “怎么了怎虫?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長困介。 經(jīng)常有香客問我大审,道長,這世上最難降的妖魔是什么座哩? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任徒扶,我火速辦了婚禮,結(jié)果婚禮上根穷,老公的妹妹穿的比我還像新娘姜骡。我一直安慰自己导坟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布圈澈。 她就那樣靜靜地躺著惫周,像睡著了一般。 火紅的嫁衣襯著肌膚如雪康栈。 梳的紋絲不亂的頭發(fā)上递递,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音啥么,去河邊找鬼登舞。 笑死,一個胖子當(dāng)著我的面吹牛悬荣,可吹牛的內(nèi)容都是我干的菠秒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼氯迂,長吁一口氣:“原來是場噩夢啊……” “哼践叠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嚼蚀,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤禁灼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后驰坊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匾二,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年拳芙,在試婚紗的時候發(fā)現(xiàn)自己被綠了察藐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡舟扎,死狀恐怖分飞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情睹限,我是刑警寧澤譬猫,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站羡疗,受9級特大地震影響染服,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜叨恨,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一柳刮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦秉颗、人聲如沸痢毒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哪替。三九已至,卻和暖如春菇怀,著一層夾襖步出監(jiān)牢的瞬間凭舶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工敏释, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留库快,地道東北人摸袁。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓钥顽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親靠汁。 傳聞我的和親對象是個殘疾皇子蜂大,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355