吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

數(shù)據(jù)結(jié)構(gòu)與算法分析:最大子序列和問題之算法優(yōu)化

lviY_AI_shequ ? 來源:未知 ? 作者:李倩 ? 2018-04-26 17:07 ? 次閱讀

算法一:窮舉式地嘗試所有的可能

int maxSubsequenceSum(const int a[], int n){ int i, j, k; int thisSum, maxSum = 0; for (i = 0; i < n; i++)?? ? ? ?for (j = i; j < n; j++)?? ? ? ?{?? ? ? ? ? ?thisSum = 0;?? ? ? ? ? ?for (k = i; k < j; k++)?? ? ? ? ? ? ? ?thisSum += a[k];?? ? ? ? ? ?if (thisSum > maxSum) maxSum = thisSum; } return maxSum;}

算法復(fù)雜度為O(n^3)(三重for循環(huán))

算法二:算法一的改進(jìn)

int maxSubsequenceSum(const int a[], int n){ int i, j; int thisSum, maxSum = 0; for (i = 0; i < n; i++)?? ?{?? ? ? ?thisSum = 0;?? ? ? ?for (j = i; j < n; j++)?? ? ? ?{?? ? ? ? ? ?thisSum += a[j];?? ? ? ? ? ?if (thisSum > maxSum) maxSum = thisSum; } } return maxSum;}

該算法去除了算法一中不必要的計(jì)算,時(shí)間復(fù)雜度為O(n^2)(兩重for循環(huán))。

算法三:分治(divide-and-conquer)策略

分治策略:

分:把問題分成若干個(gè)(通常是兩個(gè))規(guī)模相當(dāng)?shù)淖訂栴},然后遞歸地對(duì)它們求解。

治:將若干個(gè)問題的解4合并到一起并可能再做少量的附加工作,最后得到整個(gè)問題的解。

在這個(gè)問題中,最大子序列和可能在三處出現(xiàn):即左半部序列、右半部序列、穿過中部從而占據(jù)左右兩半部分的序列。前兩種情況可以通過遞歸求解。而遞歸的基準(zhǔn)情況(base cases)是序列只有一個(gè)元素(left == right),若該元素大于0,則返回該元素,否則返回0。第三種情況的最大和可以通過分別求出左邊部分(包含左半部分最后一個(gè))的最大和以及右邊部分(包含右邊部分的第一個(gè))的最大和,再將它們相加得到。

int maxSubsequenceSum(const int a[], int left, int right)

{

int i, mid, maxLeftSum, maxRightSum;

int maxLeftBorderSum, leftBorderSum;

int maxRightBorderSum, rightBorderSum;

if (left == right) { /*基準(zhǔn)情況*/

if (a[left] >= 0)

return a[left];

else

return 0;

}

mid = left + (right - left) / 2;

maxLeftSum = maxSubsequenceSum(a, left, mid); /*左半部分的最大和*/ maxRightSum = maxSubsequenceSum(a, mid+1, right); /*右半部分的最大和*/

/*下面求穿過中點(diǎn)的最大和*/

maxLeftBorderSum = 0, leftBorderSum = 0;

for (i = mid; i >= left; i--)

/*中點(diǎn)及其以左的最大和*/

{

leftBorderSum += a[i];

if (leftBorderSum > maxLeftBorderSum)

maxLeftBorderSum = leftBorderSum;

}

maxRightBorderSum = 0, rightBorderSum = 0;

for (i = mid+1; i <= right; i++) ? /*中點(diǎn)以右的最大和*/?

{

rightBorderSum += a[i];

if (rightBorderSum > maxRightBorderSum)

maxRightBorderSum = rightBorderSum;

}

/*返回三部分中的最大值*/

return max3(maxLeftSum, maxRightSum, maxLeftBorderSum+maxRightBorderSum);

}

int max3(int a, int b, int c)

{

int maxNum = a;

if (b > maxNum)

maxNum = b;

if (c > maxNum)

maxNum = c;

return maxNum;

}

以序列2,4,-1,-5,4,-1為例,其左半部分最大和為2 + 4 = 6;右半部分最大和為4,穿過中心的最大和為(-1 + 4 + 2)+ (-5 + 4)= 0。故該序列的最大子序列和為max(6,4,0)= 6。時(shí)間復(fù)雜度分析:假設(shè)T(n)為求解大小為n的最大子序列和問題所花費(fèi)的時(shí)間。當(dāng)n = 1是,T(1) = O(1);當(dāng)n > 1時(shí),兩次遞歸花費(fèi)的總時(shí)間為2T(n/2),兩個(gè)并列的for循環(huán)花費(fèi)的時(shí)間是O(len(left)+len(right)) = O(n),一共為2T(n/2)+O(n)。綜上可列如下方程組:

T(1) = 1T(n) = 2T(n/2) + O(n)

事實(shí)上,上述方程組常常通用于分治算法,由方程組可算出T(n) = O(nlogn)。

算法四:

算法三利用遞歸較好的解決了最大子序列和問題,但仔細(xì)分析,在遞歸過程中,同一個(gè)元素很可能多次被操作,有沒有更高效的算法?先上代碼

int maxSubsequenceSum(const int a[], int n){ int i; int maxSum, thisSum; maxSum = thisSum = 0; for (i = 0; i < n; i++)?? ?{?? ? ? ?thisSum += a[i];?? ? ? ?if (thisSum > maxSum) maxSum = thisSum; else if (thisSum < 0)?? ? ? ? ? ?thisSum = 0;?? ?}?? ?return maxSum;?}

可以簡(jiǎn)單的分析出上述代碼的時(shí)間復(fù)雜度是O(n),比前三種都高效。它為什么是正確的?從直觀上理解:首先for循環(huán)的if語句保證了每次更新后最大和保存在maxSum中,而我們從i = 0開始掃描,假設(shè)掃描到i = t(t < n),且此時(shí)的最大和已經(jīng)保存在maxSum中,而當(dāng)前的和(thisSum)如果大于0,不管當(dāng)i > t的元素大小如何,加上thisSum總會(huì)使之后的和變大,而如果thisSum小于0,肯定會(huì)使之后的和變小,既然還會(huì)變小,那干脆就重新來過(thisSum = 0),有些另起爐灶的意味。

該算法一個(gè)附帶的優(yōu)點(diǎn)是,它只對(duì)數(shù)據(jù)進(jìn)行一次的掃描,一旦a[i]被讀入并被處理,它就不再需要記憶。因此,如果數(shù)組在磁盤或磁帶上,它就可以被順序讀入,在主存中不必儲(chǔ)存數(shù)組的任何部分。不僅如此,在任意時(shí)刻,該算法都能對(duì)它已經(jīng)讀入的數(shù)據(jù)給出子序列問題的正確答案(其他算法即前三種不具有這個(gè)特性)。具有這種特性的算法叫做聯(lián)機(jī)算法(online algorithm)。僅需要常量空間并以線性時(shí)間運(yùn)行的online algorithm幾乎是完美的算法。————《數(shù)據(jù)結(jié)構(gòu)與算法分析》(中文版第二版)

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4630

    瀏覽量

    93354
  • 磁盤
    +關(guān)注

    關(guān)注

    1

    文章

    380

    瀏覽量

    25276

原文標(biāo)題:最大子序列和問題之算法優(yōu)化

文章出處:【微信號(hào):AI_shequ,微信公眾號(hào):人工智能愛好者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    數(shù)據(jù)結(jié)構(gòu)算法分析(Java版)(pdf)

    數(shù)據(jù)結(jié)構(gòu)算法分析(Java版)(pdf)http://www.ibeifeng.com/read.php?tid=4812&u=73481【中文】Java數(shù)據(jù)結(jié)構(gòu)
    發(fā)表于 12-20 21:22

    數(shù)據(jù)結(jié)構(gòu)算法分析

    數(shù)據(jù)結(jié)構(gòu)算法分析
    發(fā)表于 06-05 10:46

    數(shù)據(jù)結(jié)構(gòu)算法分析:C語音第二版

    數(shù)據(jù)結(jié)構(gòu)算法分析:C語音第二版,經(jīng)典資料與你分析
    發(fā)表于 12-10 10:57

    C#數(shù)據(jù)結(jié)構(gòu)算法分析_ 魏寶剛

    數(shù)據(jù)結(jié)構(gòu)算法分析》描述了各種類型的數(shù)據(jù)結(jié)構(gòu),包括線性表、樹、堆、圖,以及查找、排序等算法。自始至終將
    發(fā)表于 12-15 16:46 ?0次下載
    C#<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>和<b class='flag-5'>算法</b><b class='flag-5'>分析</b>_ 魏寶剛

    數(shù)據(jù)結(jié)構(gòu)算法分析(C語言版)

    電子發(fā)燒友網(wǎng)站提供《數(shù)據(jù)結(jié)構(gòu)算法分析(C語言版).txt》資料免費(fèi)下載
    發(fā)表于 11-28 11:05 ?0次下載

    數(shù)據(jù)結(jié)構(gòu)算法分析C++描述(第3版)

    電子發(fā)燒友網(wǎng)站提供《數(shù)據(jù)結(jié)構(gòu)算法分析C++描述(第3版).txt》資料免費(fèi)下載
    發(fā)表于 07-23 14:15 ?0次下載

    數(shù)據(jù)結(jié)構(gòu)算法習(xí)題

    數(shù)據(jù)結(jié)構(gòu)算法習(xí)題,ACM專用,刷題初期按照這個(gè)地方刷很好
    發(fā)表于 03-03 18:25 ?0次下載

    數(shù)據(jù)結(jié)構(gòu)算法

    全國(guó)C語言考試公共基礎(chǔ)知識(shí)點(diǎn)——數(shù)據(jù)結(jié)構(gòu)算法,該資料包含了有關(guān)數(shù)據(jù)結(jié)構(gòu)算法的全部知識(shí)點(diǎn)。
    發(fā)表于 03-30 14:27 ?0次下載

    數(shù)據(jù)結(jié)構(gòu)算法分析

    一部淺顯易懂的介紹數(shù)據(jù)結(jié)構(gòu)算法的書籍。
    發(fā)表于 07-14 17:12 ?0次下載

    算法數(shù)據(jù)結(jié)構(gòu)——接口

    第三章為算法數(shù)據(jù)結(jié)構(gòu),本文為3.2.3 接口。
    的頭像 發(fā)表于 09-19 17:41 ?8588次閱讀
    <b class='flag-5'>算法</b>與<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>——接口

    大牛分享平時(shí)如何學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)算法

    數(shù)據(jù)結(jié)構(gòu)算法的地位對(duì)于一個(gè)程序員來說不言而喻。今天這篇文章不是來勸你們學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)算法的,也不是來和你們說數(shù)據(jù)結(jié)構(gòu)
    的頭像 發(fā)表于 11-02 11:25 ?3018次閱讀

    數(shù)據(jù)結(jié)構(gòu)算法分析—C語言描述

    數(shù)據(jù)結(jié)構(gòu)算法分析:C語言描述》曾被評(píng)為20世紀(jì)頂尖的30部計(jì)算機(jī)著作之一,作者在數(shù)據(jù)結(jié)構(gòu)算法分析
    發(fā)表于 10-14 08:00 ?17次下載
    <b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>與<b class='flag-5'>算法</b><b class='flag-5'>分析</b>—C語言描述

    數(shù)據(jù)結(jié)構(gòu)算法分析——Java語言描述

    數(shù)據(jù)結(jié)構(gòu)算法分析——Java語言描述說明。
    發(fā)表于 05-31 14:25 ?22次下載

    JavaScrit數(shù)據(jù)結(jié)構(gòu)算法(第2版)

    JavaScrit數(shù)據(jù)結(jié)構(gòu)算法(第2版)教材下載。
    發(fā)表于 06-01 15:35 ?0次下載

    算法數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)知識(shí)分享(中)

    有哪些常見的數(shù)據(jù)結(jié)構(gòu)?基本操作是什么?常見的排序算法是如何實(shí)現(xiàn)的?各有什么優(yōu)缺點(diǎn)?本文簡(jiǎn)要分享算法基礎(chǔ)、常見的數(shù)據(jù)結(jié)構(gòu)以及排序算法
    的頭像 發(fā)表于 04-06 16:48 ?647次閱讀
    <b class='flag-5'>算法</b>和<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>基礎(chǔ)知識(shí)分享(中)
    盈得利| 百家乐官网赌博合作| 赙彩百家乐游戏规则| 香港六合彩网址| 百家乐官网大小是什么| 百家乐连线游戏下载| BET365备用网址| 百家乐官网网址| 六合彩公司| 百家乐官网技巧经| 大发888亚付宝充值| 自贡百家乐官网赌场| 大发888娱乐场下载 zhldu| 博彩百家乐官网画谜网| 大发888黄金版下载| 百家乐官网平玩法这样| 澳门金沙| 百家乐注册送彩金平台| 百家乐官网现实赌场| 百家乐公式与赌法| 破解百家乐官网公式| 大发888开户日博备用| 无锡百家乐官网的玩法技巧和规则| 金利娱乐城代理| 百家乐在线投注系统| 百家乐官网技术秘籍| 杨氏百家乐必胜公式| 网上赌百家乐官网被抓应该怎么处理 | 玩百家乐怎么能赢呢| 真人百家乐官网赌场娱乐网规则| bet365 金融| 网络百家乐破解平台| 百家乐官网视频二人麻将| 威尼斯人娱乐场 送2688元礼金领取lrm64 | 全讯网开户| 克拉克百家乐官网的玩法技巧和规则 | 大发888ios版| 澳门百家乐园游戏| 澳门百家乐官网技巧| 大发888大发888官网| 赌场百家乐技巧|