求乙個陣列的兩段連續的部分的最大和,例如1,-2,2,3,-4,結果就是6,第一段就是1,第二段就是2,3。而陣列-2,3,-1,2,-5,-6,7,-3,4,-9,2,1,第一段是3,-1,2,第二段是7,-3,4,結果就是12。
這個其實就是陣列最大連續和的擴充套件問題,經典dp問題。求最大連續和並不難,我們只需要遍歷陣列一次,並用乙個dp[i]函式記錄從陣列開頭到第i個元素的子陣列的最大和,顯然if i == 0, dp[i] = a[0], 而if i > 0, 需要考慮dp[i - 1] 的符號, 如果dp[i - 1] <= 0,則dp[i] = a[i],因為前面i-1個元素最大連續和不大於0, 加上當前元素不可能大於當前元素,只會越加越小, 即小於a[i]。 而當dp[i - 1] > 0時, dp[i] = dp[i - 1] + a[i],原因很簡單,前面的連續和大於0, 加上當前元素a[i],肯定會大於a[i]. 有了這個思路,演算法就很簡單了。這裡時間複雜度是o(n),空間複雜度也是o(n),但我們發現我們只需要乙個最大的和,那些前面算出的和,如果不是最大,根本沒有必要儲存,我們只需維護乙個儲存當前最大和的變數就可以了,因此空間複雜度可以降低為o(1)。
要求兩段連續的部分和的最大值,可以先把陣列分成兩個各不相交的子陣列,然後分別求子陣列的最大連續和,相加最大即為所求。
#include #include #define max_length 1000
#define max(a, b) ((a) > (b) ? (a) : (b))
int errno;
int max_subarray(int *a, int len)
int max = a[0], i, sum = a[0];
for (i = 1; i < len; i++) else
max = max(max, sum);
}return max;
}int op(int *a, int len)
int i, max = int_min;
for (i = 1; i < len; i++)
return max;
}int main(int argc, char **argv)
; int b = ;
int c = ;
printf("%d\n", op(a, 5));
printf("%d\n", op(b, 4));
printf("%d\n", op(c, 2));
return 0;
}
求乙個陣列的連續子陣列的最大和
輸入乙個整型陣列,陣列中有正有負。陣列中的乙個或多個整數組成乙個子陣列。求所有子陣列的和的最大值,要求時間複雜度為o n 首先,根據題意,可能我們都會想到列舉陣列中所有的子陣列的和。我們都知道乙個長度為n的陣列,總共有n n 1 2個子陣列。計算出所有子陣列的和需要o n 2 時間。我們先來舉例分析...
求乙個陣列的最長連續子串行
分析 如果允許o nlogn 的複雜度,那麼可以先排序,可是本題要求o n 由於序列裡的元素是無序的,又要求o n 首先要想到用雜湊表。用乙個雜湊表unordered mapused 記錄每個元素是否使用,對每個元素,以該元素為中心,往左右擴張,直到不連續為止,記錄下最長的長度。class solu...
求乙個陣列的子集
該題是力扣上面的乙個題,感覺思路不錯就摘抄下來做個筆記。以後準備定期耍上面的題來提高一下自己的演算法基礎。題目描述如下 給定一組不含重複元素的正數陣列 nums,返回該陣列所有可能的子集 冪集 說明 解集不能包含重複的子集。示例 輸入 nums 1,2,3 輸出 3 1 2 1,2,3 1,3 2,...