題目連結: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;
}
};