【算導(dǎo)】分治法求解最大子數(shù)組

任意子數(shù)組必然是以下三種情況之一:

1.完全在a[low...mid]中。

2.完全在a[mid+1...high]中。

3.跨越了數(shù)組中點(diǎn)。

若結(jié)果為1或2,則可通過遞歸求解,若結(jié)果為3,則可通過一個(gè)線性時(shí)間復(fù)雜度的函數(shù)求解:

FIND-CROSS(a,low,mid,high)
    leftsum=0;
    sum=0;
    for(int i=mid;i>=low;i--)
    {
        sum+=a[i];
        leftsum=max(leftsum,sum);
    }
    rightsum=0;
    sum=0;
    for(int i=mid;i<high;i++)
    {
        sum+=a[i];
        rightsum=max(rightsum,sum);
    }
return leftsum+rightsum

最后寫一個(gè)總函數(shù):

FIND(a,low,high)
    if(low==high)
        return a[low]
    else
    {
        mid=(low+high)/2
        b=FIND(a,low,mid)
        c=FIND(a,mid+1,high)
        d=FIND-CROSS(a,low,mid,high)
        return max(b,c,d);
    }

時(shí)間復(fù)雜度O(nlogn)

一個(gè)更優(yōu)化的方法,時(shí)間復(fù)雜度O(n)
從頭遍歷,每遍歷一個(gè)數(shù),加到sum中,與當(dāng)前最大值res比較更新res,當(dāng)sum小于0時(shí),sum、
等于0,相當(dāng)于把之前的所有結(jié)果清零,從下一個(gè)數(shù)重新比較并繼續(xù)更新res

int maxSubArray(vector<int> nums) {
    int ge = nums.size();
    if (ge == 0)
        return 0;
    int sum = 0;
    int res = nums[0];
    for (int i = 0; i < ge; i++)
    {
        sum += nums[i];
        res = max(sum, res);
        if (sum < 0)
            sum = 0;        
    }
    return res;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容