1. 程式人生 > >LeetCode 53. 最大子序和 Maximum Subarray(C語言)

LeetCode 53. 最大子序和 Maximum Subarray(C語言)

題目描述:

給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。

示例:

輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6。

進階:

如果你已經實現複雜度為 O(n) 的解法,嘗試使用更為精妙的分治法求解。

題目解答:

方法1:暴力法

求每個數字到其後每個數字的連續和,求出最大值。
執行時間200ms左右,程式碼如下。

int maxSubArray(int* nums, int numsSize) {
    int
i = 0, j = 0; int max = nums[0]; for(i = 1; i < numsSize; i++) { nums[i] = nums[i] + nums[i - 1]; if(max < nums[i]) max = nums[i]; } for(i = 0; i < numsSize; i++) { for(j = i + 1; j < numsSize; j++) { if(nums[j] - nums[
i] > max) max = nums[j] - nums[i]; } } return max; }

方法2:動態規劃

sum儲存使用上一個數字的連續和,sum加上當前位置數字,如果和大於0,則說明可以繼續向後;小於0則說明,當前位置是一個負數,應該從下一個數字重新開始。同時也要不斷更新max
執行時間4ms,程式碼如下。

int maxSubArray(int* nums, int numsSize) {
    int i = 0, sum = 0;
    int max = nums[0];
    for
(i = 0; i < numsSize; i++) { sum += nums[i]; if(max < sum) max = sum; if(sum < 0) sum = 0; } return max; }

方法3:貪心法

尋找從開始位置的最小和,開始位置到當前位置連續和與其前邊的最小值差值sum - min,即為到當前位置前邊的最大連續和。
執行時間4ms,程式碼如下。

int maxSubArray(int* nums, int numsSize) {
    int i = 0, sum = 0, min = 0;
    int max = nums[0];
    for(i = 0; i < numsSize; i++) {
        sum += nums[i];
        if(sum - min > max)
            max = sum - min;
        if(sum < min)
            min = sum;
    }
    return max;
}

方法4:分治法

分成子問題解決。結構體中l表示陣列中以最左側數字起的連續最大值,max表示陣列中的連續最大值,r表示陣列中以最右側數字為終點的連續最大值,sum表示陣列之和。
執行時間4ms,程式碼如下。

struct val {
    int l;
    int max;
    int r;
    int sum;
};
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a > b ? b : a)
struct val maxSub(int* nums, int n) {
    if(n == 1) {
        struct val t = {nums[0], nums[0], nums[0], nums[0]};
        return t;
    }
    struct val v1 = maxSub(nums, n / 2);
    struct val v2 = maxSub(nums + n / 2, n - n / 2);
    int l = max(v1.l, v1.sum + v2. l);
    int max = max(max(v1.max, v2.max), v1.r + v2.l);
    int r = max(v2.r, v1.r + v2.sum);
    int sum = v1.sum + v2.sum;
    struct val t = {l, max, r, sum};
    return t;
}
int maxSubArray(int* nums, int numsSize) {
    struct val v = maxSub(nums, numsSize);
    return v.max;
}