剖析遞迴行為和遞迴行為時間複雜度的估算
乙個遞迴行為的例子
t(n) = a*t(n/b) + o(n^d)
1) log(b,a) > d -> 複雜度為o(n^log(b,a))
2) log(b,a) = d -> 複雜度為o(n^d * logn)
3) log(b,a) < d -> 複雜度為o(n^d)
補充閱讀:www.gocalf.com/blog/algorithm-complexity-and-mastertheorem.html
t(n)表示父問題樣本量,t(n/b)表示被拆成子問題的樣本量,a表是一共發生多少次,o(n^d)表示除去呼叫子過程之外,剩下的代價是多少。
什麼時候用master公式:劃分成子過程的規模是一樣的
舉例:從乙個陣列中找最大值
思路:將陣列分為左右倆部分,左邊(l)最大值和右邊(r)最大值比較,最大的數就是最大值。具體**如下:
public static void main(string args) ;
system.out.println(getmax(arr,0,arr.length-1));
}private static int getmax(int arr, int l, int r)
int mid = (l+r)/2;
//maxleft這個引數指望著 getmax方法返回 儲存所有的遞迴資訊,將所有的引數,所有的變數壓入棧中
int maxleft = getmax(arr, l, mid);
int maxright = getmax(arr, mid + 1, r);
return math.max(maxleft,maxright);
}
遞迴行為時間複雜度式子一:t(n)= at(n/b)+o(n^d)等式左邊表示樣本大小為n的時間複雜度。
在找出陣列最大值的過程中,有等式t(n)= 2*t(n/2)+o(1),樣本量為n/2的過程跑了2次,當跑完這個子過程後,比對較大的數並且返回,是乙個常數操作,時間複雜度為o(1)。
所以式子一中 t(n)表示原始大小樣本量,n/b 表示子過程的樣本量,o(n^d)表示除去呼叫子過程之外,剩下的代價是多少。
所以,例子中a=2,b=2,d=0
時間複雜度o(n*logn),額外空間複雜度o(n)
歸併排序在上面講解了遞迴行為就很簡單了。乙個陣列先左側部分排好序,再右側部分排好序。然後整體利用外排的方式排好序。
假設乙個陣列:5,3,6,)2,0,1,
0)先左側排好序,再右側排好序,整體再排好序。左側部分排好序是3,5,6,而右側部分排好序是0,1,2,接下來整體排序。
1)準備乙個輔助陣列,採用外排方式
2)左邊部分準備乙個下標a指向3,右邊準備乙個下標b指向0,哪乙個小,就向輔助陣列插入
則分析公式t(n)= at(n/b)+o(n^d),其中a=2,b=2,d=1,所以歸併排序時間複雜度為o(n*logn)
具體**如下:
public static void mergesort(int arr)
mergesort(arr, 0, arr.length - 1);
}public static void mergesort(int arr, int l, int r)
int mid = l + ((r - l) >> 1);
mergesort(arr, l, mid);
mergesort(arr, mid + 1, r);
merge(arr, l, mid, r);
}public static void merge(int arr, int l, int m, int r)
//當p2已經到達陣列末尾,繼續填充p1,倆個必有且只有乙個越界
while (p1 <= m)
while (p2 <= r)
//將help陣列填回arr
for (i = 0; i < help.length; i++)
}
在乙個陣列中,每乙個數左邊比當前數小的數累加起來,叫做這個陣列的小和。求乙個陣列 的小和。
例子:[1,3,4,2,5]
1左邊比1小的數,沒有;
3左邊比3小的數,1;
4左邊比4小的數,1、3;
2左邊比2小的數,1;
5左邊比5小的數,1、3、4、2;
所以小和為1+1+3+1+1+3+4+2=16
在乙個陣列中,左邊的數如果比右邊的數大,則折兩個數構成乙個逆序對,請列印所有逆序對。
這種題可以用歸併排序做出解,問題的實質:如果當前數是current,我們找的是,我們查詢右邊有多少個數比current大,個數*current
舉例:陣列1,3,4,2,5
1)先分成左右部分,長度為奇數,左部分可以是3個,也可以是2個,假設分成左邊3個。左邊1,3,4,右邊2,5
2)1,3,4再分治,分為1,3和4;2,5拆成2和5
3)1,3分為1,3
4)merge過程中求所有的小和。
5)準備輔助陣列,拷貝1,3,計算小和 1
6)merge1,3和 4,準備乙個輔助陣列, 計算小和 1,3
右側部分同理,產生小和2
左側1,3,4,右側2,5進行最後merge過程產生小和,
1)準備乙個輔助陣列,左側a指向1,右側b指向2
2)a比b小,在右側有 多少個比1 大 ,包括2在內有2個數 ,產生 2*1的小和
3)a來到3位置,b是2,a是3,不產生任何小和,然後b來到5位置
4)3比5小,產生乙個 1*3 的小和,同時a來到4位置
5)產生乙個 1*4 的小和
具體**如下:
public static int smallsum(int arr)
return mergesort(arr, 0, arr.length - 1);
}public static int mergesort(int arr, int l, int r)
int mid = l + ((r - l) >> 1);
//左側部分小和+右側部分小和+合併過程產生的小和
return mergesort(arr, l, mid) + mergesort(arr, mid + 1, r) + merge(arr, l, mid, r);
}public static int merge(int arr, int l, int m, int r)
while (p1 <= m)
while (p2 <= r)
for (i = 0; i < help.length; i++)
return res;
}
除了紅色部分,小和問題和歸併排序**一模一樣
能夠形成1,2,3說明1在當時merge的時候已經計算了
linux一切皆是檔案 LINUX一切皆檔案
只要用過linux的筒子,或者保守點說接觸到一些linux思想的同志肯定聽說過這樣一句話,在linux下,一切皆是檔案 不錯,今天walfred將在快速上手linux裝置驅動這一塊,談談linux的裝置也符合 一切皆是檔案 的思想在linux裝置驅動模型應用。如果你不理解linux裝置模型,請看下面...
EQ決定一切
eo是 情緒智商 的簡稱,由美國哈佛大學心理系教授丹尼爾 戈爾曼在1995年出版的書中提出。戈爾曼認為,eq包括抑制衝動 延遲滿足的克制力,包含了如何調適自己的情緒如何設身處地地為別人著想 感受別人的 感受的能力,以及如何建立良好的人際關係 培養自動自發的心靈動力 簡單說來,eq是一種為人的涵養,是...
心態決定一切
心態決定一切 1 放下壓力 累與不累,取決於自己的心態 心靈的房間,不打掃就會落滿灰塵。蒙塵的心,會變得灰色和迷茫。我們每天都要經歷很多事情,開心的,不開心的,都在心裡安家落戶。心裡的事情一多,就會變得雜亂無序,然後心也跟著亂起來。有些痛苦的情緒和不愉快的記憶,如果充斥在心裡,就會使人委靡不振。所以...