演算法學習筆記(一)

2021-10-09 06:13:34 字數 3846 閱讀 9363

mapreduce(分治演算法的應用) 是 google 大資料處理的三駕馬車之一,另外兩個是 gfs 和 bigtable。它在倒排索引、pagerank 計算、網頁分析等搜尋引擎相關的技術中都有大量的應用。

儘管開發乙個 mapreduce 看起來很高深,感覺遙不可及。實際上,萬變不離其宗,它的本質就是分治演算法思想,分治演算法。如何理解分治演算法?為什麼說 mapredue 的本質就是分治演算法呢?

分治演算法的主要思想是將原問題遞迴地分成若干個子問題,直到子問題滿足邊界條件,停止遞迴。將子問題逐個擊破(一般是同種方法),將已經解決的子問題合併,最後,演算法會層層合併得到原問題的答案。

.):# 不斷切分的終止條件

if problem is

none

: print_result

return

# 準備資料

data=prepare_data(problem)

# 將大問題拆分為小問題

subproblems=split_problem(problem, data)

# 處理小問題,得到子結果

subresult1=self.divide_conquer(subproblems[0]

,p1,

..…)

subresult2=self.divide_conquer(subproblems[1]

,p1,..

.)subresult3=self.divide_conquer(subproblems[2]

,p1,

.…)# 對子結果進行合併 得到最終結果

result=process_result(subresult1, subresult2, subresult3,..

.)​ 通過應用舉例分析理解分治演算法的原理其實並不難,但是要想靈活應用並在程式設計中體現這種思想中卻並不容易。所以,這裡這裡用分治演算法應用在排序的時候的乙個例子,加深對分治演算法的理解。

一般通過計算有序對或者逆序對的個數,來表示資料的有序度或逆序度。

假設我們有n個資料,我們期望資料從小到大排列,那完全有序的資料的有序度就是 n(n

−1)/

2n(n-1)/2

n(n−1)

/2,逆序度等於 0;相反,倒序排列的資料的有序度就是 0,逆序度是 n(n

−1)/

2n(n-1)/2

n(n−1)

/2。q:如何程式設計求出一組資料的有序對個數或者逆序對個數呢?

因為有序對個數和逆序對個數的求解方式是類似的,所以這裡可以只思考逆序對(常接觸的)個數的求解方法。

方法2

leetcode169題

以分治實現

class

solution

(object):

defmajorityelement

(self, nums)

:# 【不斷切分的終止條件】

ifnot nums:

return

none

iflen

(nums)==1

:return nums[0]

# 【準備資料,並將大問題拆分為小問題】

left = self.majorityelement(nums[

:len

(nums)//2

])right = self.majorityelement(nums[

len(nums)//2

:])# 【處理子問題,得到子結果】

# 【對子結果進行合併 得到最終結果】

if left == right:

return left

if nums.count(left)

> nums.count(right)

:return left

else

:return right

leetcode53題由於左右區間計算累加和的方向不一致,因此,左右區間直接合併相加之後就是整個區間的和

最終返回左區間的元素、右區間的元素、以及整個區間(相對子問題)和的最大值

以分治實現

class

solution

:def

maxsubarray

(self, nums: list[

int])-

>

int:

# 【不斷切分的終止條件】

n =len(nums)

if n ==1:

return nums[0]

# 【準備資料,並將大問題拆分為小問題】

# 獲得左右最大子序和

left = self.maxsubarray(nums[

:n//2]

) right = self.maxsubarray(nums[n//2:

])# 【處理子問題,得到子結果】

# 獲得穿過中間的最大值

# 從右到左計算左側的最大子序和

max_l = nums[n//2-

1]# 左側最大子序和,初始為最右邊元素

tmp =

0# tmp用來記錄連續子陣列的和

for i in

range

( n//2-

1,-1

,-1)

:# 從右到左遍歷

tmp += nums[i]

max_l =

max(tmp ,max_l)

# 從左到右計算右側的最大子序和

max_r = nums[n//2]

# 右側最大子序和,初始為最左邊元素

tmp =

0for i in

range

(n//

2,n)

:# 從左到右遍歷

tmp += nums[i]

max_r =

max(tmp,max_r)

# 【對子結果進行合併 得到最終結果】

# 返回三個中的最大值

return

max(left,right,max_l+ max_r)

leetcode50題最終返回p以分治實現

class

solution

:def

mypow

(self, x:

float

, n:

int)

->

float

:# 處理n為負的情況

if n <0:

x =1/x

n =-n # 【確定不斷切分的終止條件】

if n ==0:

return

1# 【準備資料,並將大問題拆分為小的問題】

if n%2==

1:# 【處理小問題,得到子結果】

return x * self.mypow(x,n-1)

# 【對子結果進行合併 得到最終結果】

return self.mypow(x*x,n/

2)

演算法 學習筆記

1.輸入輸出演算法至少有乙個或多個輸出 2.有窮性 3.確定性 4.可行性 1.正確性a.演算法程式沒有語法錯誤 b.演算法程式對於合法的輸入資料能夠產生滿足要求的輸出結果 c.演算法程式對於非法的輸入資料能夠得出滿足規格說明的結果 d.演算法對於精心選擇的,甚至刁難的測試資料都有滿足要求的輸出結果...

演算法學習筆記

複雜度分析 1.只關注迴圈次數最多的一行 2.總複雜度等於量級最大 的複雜度 3.巢狀 的複雜度等於巢狀 內外複雜度的乘積 單鏈表結構和順序儲存結構的優缺點 儲存分配方式 時間效能 空間效能 單鏈表結構 用一組任意的儲存單元存放線性表元素 查詢 o n 插入和刪除 找到某位置的指標後,插入和刪除的時...

演算法學習筆記

影象分割是機器視覺後續處理的基礎,通過分割提取影象中的目標區域,方便後續進一步分析處理。分水嶺分割演算法 傳統的分水嶺演算法,是基於數學形態學的分割方法。其基本思想是,將2d影象視為3d地形 其中,畫素的座標 地形的位置,畫素的灰度 地形的高度 每乙個區域性極小值及其周圍區域稱為集水盆地,而集水盆地...