分治法 最大子序和(Leetcode 53)

2021-10-02 18:26:48 字數 2266 閱讀 9420

找到公式:

dp[i]=max(dp[i-1]+nums[i],nums[i])

其中dp[i]表示以nums[i]結尾的最大連續和。

這個公式就理解成:

對於當前這個數字,要麼前面的對你有益,你加上;

要麼前面對你無益,你不需要前面的。

所以,最後再額外使用乙個空間,用來保留目前為止認為的最大值即可。

分治法,問題劃分成子問題,再合併。

連續子串的劃分如下:

1、左半邊子串

2、右半邊子串

3、橫跨中間值的任意子串

確實就是這三類了,求出這三類的結果,然後取最大值即可。

思考的時候可以這樣想,每個子串又可以分治,遞迴之後可以認為只有陣列只有三個值:[a,b,c]。當然,這其實不是最終結果,只是便於思考。

所以函式可以這樣寫:

if(length==1)else
left和right比較簡單,遞迴到最後,肯定是length為1。 問題在於,mid怎麼求。

mid的求解思路有點暴力:

1、從mid開始,往左遍歷相加,使用maxleft記錄最大值。

2、從mid+1開始,往右遍歷相加,使用rightleft記錄最大值,小於0就丟棄。

所以函式就變成了下面這個樣子:

function maxsubarray(int nums,int start,int end)

int center=(start+end)/2;

int left=maxsubarray(nums,start,center);

int right=maxsubarray(nums,center+1,end);

int mid=getmid();//這裡為了思路清晰沒有詳述,求解思路就是上面所說,具體**在下面

return max(left,mid,right);

}

最後補充一下,讓我困惑了一會兒的點,那就是這個函式有兩個return,在幹嘛?

概略地,

第乙個return是遞迴的return,或者理解為左右子串的return

第二個return是分治的return,理解為子串的return,包括中間子串

實在想不清楚,就像我之前說的,用[2,-1,3]這個陣列理一下。

下面是具體**

public int maxsubarray(int nums) 

private int maxsubarraydividewithborder(int nums, int start, int end)

// 計算中間值

int center = (start + end) / 2;

int leftmax = maxsubarraydividewithborder(nums, start, center); // 計算左側子串行最大值

int rightmax = maxsubarraydividewithborder(nums, center + 1, end); // 計算右側子串行最大值

// 下面計算橫跨兩個子串行的最大值

// 計算包含左側子串行最後乙個元素的子串行最大值

int leftcrossmax = integer.min_value; // 初始化乙個值

int leftcrosssum = 0;

for (int i = center ; i >= start ; i --)

// 計算包含右側子串行最後乙個元素的子串行最大值

int rightcrossmax = nums[center+1];

int rightcrosssum = 0;

for (int i = center + 1; i <= end ; i ++)

// 計算跨中心的子串行的最大值

int crossmax = leftcrossmax + rightcrossmax;

// 比較三者,返回最大值

return math.max(crossmax, math.max(leftmax, rightmax));

}

歡迎指導。

最大子序和 DP,分治

給定乙個整數陣列 nums 找到乙個具有最大和的連續子陣列 子陣列最少包含乙個元素 返回其最大和。示例 輸入 2,1,3,4,1,2,1,5,4 輸出 6 解釋 連續子陣列 4,1,2,1 的和最大,為 6。高階 如果你已經實現複雜度為 o n 的解法,嘗試使用更為精妙的分治法求解。以a 0 結尾的...

leetcod 53 最大子序和演算法理解

先上 class solution return max 設sum i 為以第i個元素結尾且和最大的連續子陣列。假設對於元素i,所有以它前面的元素結尾的子陣列的長度都已經求得,那麼以第i個元素結尾且和最大的連續子陣列實際上,要麼是以第i 1個元素結尾且和最大的連續子陣列加上這個元素,要麼是只包含第i...

最大子段和之分治法

問題描述 給定乙個陣列,找出其中可以構成最大數的子段,需要注意的是,這個不同於最大子串行求和 最大字段求和 字段必須是連續的 最大子串行求和 子串行只要是包含在原來的序列中即可 舉個例子 1 4 3 1 5 1 4 5 2 求上述的陣列中的最大欄位和,不難得知,最大子段和就是 10 也就是子段4 3...