劍指offer - 連續(xù)子數(shù)組的最大和

題目

輸入一個(gè)整型數(shù)組,數(shù)組里有正數(shù)也有負(fù)數(shù)涕癣。數(shù)組中一個(gè)或連續(xù)多個(gè)整數(shù)組成一個(gè)子數(shù)組哗蜈。求所有子數(shù)組的和的最大值。要求時(shí)間復(fù)雜度為O(n)

例如:輸入數(shù)組為{1坠韩,-2距潘,3,10只搁,-4音比,7,2氢惋,-5 }洞翩,和最大的子數(shù)組為{3,10焰望,-4骚亿,7,2}熊赖,因此輸出為該子數(shù)組的和為18

分析

從頭到尾累加數(shù)組中的每個(gè)數(shù)字來分析規(guī)律

  • 初始化和為0
  • 第一步加上第一個(gè)數(shù)字1循未,此時(shí)和為1
  • 第二步加上數(shù)字-2,和為-1
  • 第三步加上數(shù)字3,這里注意:之前累加和為-1的妖,小于0绣檬,如果用-1加上3,得到和為2嫂粟,比3本身還小娇未。也就是說,從第一個(gè)數(shù)字開始的子數(shù)組和小于從第三個(gè)數(shù)字開始的子數(shù)組的和星虹。因此零抬,可以不用考慮從第一個(gè)數(shù)字開始的子數(shù)組,之前的累加的和被拋棄
  • 現(xiàn)在從第3個(gè)數(shù)字重新開始累加宽涌,此時(shí)和為3
  • 第四步加10平夜,得到和13
  • 第五步加上-4,得到和為9卸亮。可以看到結(jié)果比之前的和要小忽妒,因此把之前得到的和13保存下來,因?yàn)樗锌赡苁亲畲蟮淖訑?shù)組的和
  • 第六步加上數(shù)字7兼贸,結(jié)果為16段直,此時(shí)和比之前最大的和13大,所以更新子數(shù)組的最大和
  • 第七步加上2溶诞,累加得到和為18鸯檬,同時(shí)更新最大子數(shù)組和
  • 第八步加上最大一個(gè)數(shù)字-5,由于得到的和13小于之前的18螺垢。因此最大的子數(shù)組和為18

總結(jié)

在每次元素累加和小于0時(shí)喧务,從下一個(gè)元素重新開始累加。否則直接累加枉圃,更新最大值功茴。

算法實(shí)現(xiàn)

#include <iostream>

bool invalidInput = false; // 無效輸入

int findGreatestSumOfSubArray(int *pData, int length) {
    if ((pData == nullptr) || (length <= 0)) {
        invalidInput = true;
        return 0;
    }

    int currentSum = 0; // 當(dāng)前求和值
    int greatestSum = 0x80000000; // 最大求和值
    for (int i = 0; i < length; i++) {
        if (currentSum <= 0) { // 當(dāng)前求和結(jié)果值小于0 
            currentSum = pData[i];
        } else {
            currentSum += pData[i]; // 累加
        }
        
        if (currentSum > greatestSum) { // 更新最大值 
            greatestSum = currentSum;
        }
    }

    return greatestSum;
}

void Test(char* testName, int* pData, int nLength, int expected, bool expectedFlag) {
    if(testName != nullptr)
        printf("%s begins: \n", testName);

    int result = findGreatestSumOfSubArray(pData, nLength);
    if(result == expected && expectedFlag == invalidInput)
        printf("Passed.\n");
    else
        printf("Failed.\n");
}

void Test1() {
    int data[] = {1, -2, 3, 10, -4, 7, 2, -5};
    Test("Test1", data, sizeof(data) / sizeof(int), 18, false);
}

void Test2() {
    int data[] = {-2, -8, -1, -5, -9};
    Test("Test2", data, sizeof(data) / sizeof(int), -1, false);
}

void Test3() {
    int data[] = {2, 8, 1, 5, 9};
    Test("Test3", data, sizeof(data) / sizeof(int), 25, false);
}

void Test4() {
    Test("Test4", nullptr, 0, 0, true);
}

int main(int argc, char* argv[]) {
    Test1();
    Test2();
    Test3();
    Test4();

    return 0;
}

暴力求解

如果不要求時(shí)間復(fù)雜度為O(n),很容易想到的就是雙重遍歷求和讯蒲,時(shí)間復(fù)雜度為O(n2)

先找出從第1個(gè)元素開始的最大子數(shù)組痊土,而后再從第2個(gè)元素開始找出從第2個(gè)元素開始的最大子數(shù)組,依次類推墨林,比較得出最大的子數(shù)組赁酝。

nt maxSubArray(int *array, int length) {
    int maxSum = 0x80000000;

    if ((array == nullptr) || (length <= 0)) {
        return 0;
    }

    for (int i = 0; i < length; i++)
    {
        int currentSum = 0;
        for (int j = i; j < length; j++)
        {
            currentSum += array[j];
            if (currentSum > maxSum)
            maxSum = currentSum;   
        }
    }
    return maxSum;
}

參考

《劍指offer》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市旭等,隨后出現(xiàn)的幾起案子酌呆,更是在濱河造成了極大的恐慌,老刑警劉巖搔耕,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隙袁,死亡現(xiàn)場離奇詭異痰娱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)菩收,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門梨睁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人娜饵,你說我怎么就攤上這事坡贺。” “怎么了箱舞?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵遍坟,是天一觀的道長。 經(jīng)常有香客問我晴股,道長愿伴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任电湘,我火速辦了婚禮隔节,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胡桨。我一直安慰自己官帘,他們只是感情好瞬雹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布昧谊。 她就那樣靜靜地躺著,像睡著了一般酗捌。 火紅的嫁衣襯著肌膚如雪呢诬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天胖缤,我揣著相機(jī)與錄音尚镰,去河邊找鬼。 笑死哪廓,一個(gè)胖子當(dāng)著我的面吹牛狗唉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涡真,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼分俯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了哆料?” 一聲冷哼從身側(cè)響起缸剪,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎东亦,沒想到半個(gè)月后杏节,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年奋渔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了镊逝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嫉鲸,死狀恐怖蹋半,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情充坑,我是刑警寧澤减江,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站捻爷,受9級(jí)特大地震影響辈灼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜也榄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一巡莹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧甜紫,春花似錦降宅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拓型,卻和暖如春额嘿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背劣挫。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工册养, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人压固。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓球拦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親帐我。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坎炼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 題目描述 [連續(xù)子數(shù)組的最大和] HZ偶爾會(huì)拿些專業(yè)問題來忽悠那些非計(jì)算機(jī)專業(yè)的同學(xué)。今天測試組開完會(huì)后,他又發(fā)話...
    一只可愛的檸檬樹閱讀 168評(píng)論 0 0
  • 本文首發(fā)于我的個(gè)人博客:尾尾部落 題目描述 HZ偶爾會(huì)拿些專業(yè)問題來忽悠那些非計(jì)算機(jī)專業(yè)的同學(xué)焚刚。今天測試組開完會(huì)后...
    繁著閱讀 295評(píng)論 0 0
  • 1点弯、題目描述 輸入一個(gè) 非空 整型數(shù)組,數(shù)組里的數(shù)可能為正矿咕,也可能為負(fù)抢肛。 數(shù)組中一個(gè)或連續(xù)的多個(gè)整數(shù)組成一個(gè)子數(shù)組...
    鄧澤軍_3679閱讀 271評(píng)論 0 0
  • 愛情和面包狼钮, 修煉和烹調(diào)。 愛情來的時(shí)候熱情似火捡絮, 面包熟的時(shí)侯滾燙燒燒 愛情久了會(huì)倦 面包久了...
    開在夏末的花立在他山之石閱讀 306評(píng)論 0 3
  • 早點(diǎn)時(shí)熬芜,我在向我媽說老二懂事,我告訴他福稳,先睡下涎拉,等媽媽幫姐姐穿完衣服后給弟弟穿衣服嘹吨,弟弟就乖乖的睡下了巷帝。老二沒聽懂...
    寶貝我們一起成長閱讀 290評(píng)論 0 0