LeetCode53. 最大子陣列和

Tomorrowland_D發表於2024-07-25

題目連結:https://leetcode.cn/problems/maximum-subarray/description/

題目敘述:

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

子陣列是陣列中的一個連續部分。

示例 1:

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

示例 2:

輸入:nums = [1]
輸出:1
示例 3:

輸入:nums = [5,4,-1,7,8]
輸出:23

提示:

1 <= nums.length <= 10^5
-104 <= nums[i] <= 10^4

暴力思路:

這題暴力思路十分簡單,列舉出每一組的陣列子序列,取最大值即可

暴力思路程式碼如下:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int result = INT32_MIN;
        int count = 0;
        for (int i = 0; i < nums.size(); i++) { // 設定起始位置
            count = 0;
            for (int j = i; j < nums.size(); j++) { // 每次從起始位置i開始遍歷尋找最大值
                count += nums[j];
                result = count > result ? count : result;
            }
        }
        return result;
    }
};

不過暴力解法肯定超時了!

貪心思想:

貪心貪的是哪裡呢?

如果 -2 1 在一起,計算起點的時候,一定是從 1 開始計算,因為負數只會拉低總和,這就是貪心貪的地方!

區域性最優:當前“連續和”為負數的時候立刻放棄,從下一個元素重新計算“連續和”,因為負數加上下一個元素 “連續和”只會越來越小。

全域性最優:選取最大“連續和”

區域性最優的情況下,並記錄最大的“連續和”,可以推出全域性最優。

從程式碼角度上來講:遍歷 nums,從頭開始用 count 累積,如果 count 一旦加上 nums[i]變為負數,那麼就應該從 nums[i+1]開始從 0 累積 count 了,因為已經變為負數的 count,只會拖累總和。

這相當於是暴力解法中的不斷調整最大子序和區間的起始位置。

那麼我們只需要遍歷一次陣列,當count一旦小於0了,就把count賦值為0,直接從下一位開始加,否則就會拖累正的數字!

程式碼如下:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int result=INT_MIN;
        int count=0;
        for(int i=0;i<nums.size();i++){
            count+=nums[i];
            //及時更新最大值
            if(count>result) result=count;
            //如果count小於0,直接從下一位開始
            if(count<0) count=0;
        }
        return result;
    }
};

相關文章