给你一个整数数组 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 <= 105
-104 <= nums[i] <= 104
方法一:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int result = INT32_MIN;
int count = 0;
for(int i =0;i<nums.size();i++){
count+=nums[i];
if(count > result) result = count;
if(count <= 0) count = 0;
}
return result;
}
};
方法二:动态规划
使用dp数组,需要n的空间复杂度的方法。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
for (int i = 1; i < dp.size(); i++) {
dp[i] = max(nums[i], dp[i - 1] + nums[i]);
}
return *max_element(dp.begin(), dp.end());
}
};
max_element可以找到dp数组中最大值的迭代器。获取其指向元素的值。但是额外开辟数组占据了O(n)的空间复杂度。
改进后方法:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int pre = 0, maxAns = nums[0];
for (const auto &x: nums) {
pre = max(pre + x, x);
maxAns = max(maxAns, pre);
}
return maxAns;
}
};
使用临时变量pre来存储dp[i]的情况,直接对全局maxAnx进行比较。空间复杂度为O(1)。
const auto &x:nums 和 auto &x:nums 的区别
-
const auto &x: nums:
const auto &x
声明了一个常量引用x
,该引用指向nums
。这意味着你不能通过x
修改nums
中的元素,并且x
的类型是根据nums
中元素的类型进行推导的。由于是常量引用,x
无法修改nums
中的元素,但可以安全地读取它们。- 这种方式适用于你不需要修改
nums
中的元素,只是需要对其进行读取操作的情况。
-
auto &x: nums:
auto &x
声明了一个引用x
,该引用指向nums
。它将nums
中的元素类型推导给x
,允许通过x
修改nums
中的元素。- 这种方式适用于你需要修改
nums
中的元素的情况。