今天需求有点多,先更新一道简单些的题
题目描述:
题号:53
题目描述:
给你一个整数数组 nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
解题思路:
思路一:动态规划(可优化)
算法思路:
1、用一个数组 dp[i] = max (dp[i - 1] + num[i], num[i]) 记录每个 i 所在位置的从数组第一个元素到当前元素 i 的最大子数组和。当子数组的和小于当前元素的时候显然应该取当前元素。
2、边计算边用一个变量 answer 记录最大的子数组和,因为它可能不是最后dp数组的一个元素。
时间复杂度:O(N)
空间复杂度:O(N)
C++
// C++
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size() == 0) {
return 0;
}
vector<int> dp(nums.size(), 0);
// 边界条件
dp[0] = nums[0];
int answer = nums[0];
for(int i = 1; i < nums.size(); i++) {
dp[i] = max(dp[i - 1] + nums[i], nums[i]);
answer = max(answer, dp[i]);
}
return answer;
}
};
go
// go
func maxSubArray(nums []int) int {
if len(nums) == 0 {
return 0
}
dp := make([]int, len(nums))
// 边界条件
answer := nums[0]
dp[0] = nums[0]
for i := 1; i < len(nums); i++ {
dp[i] = max(dp[i - 1] + nums[i], nums[i])
answer = max(answer, dp[i])
}
return answer
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
思路二:动态规划(已优化)
优化思路:dp[i - 1] 的前面的元素与结果无关,可以舍弃。因此用 pre 变量保存 dp[i - 1] 的值。空间复杂度下降为O(1)
时间复杂度:O(N)
空间复杂度:O(1)
C++
// C++
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size() == 0) {
return 0;
}
// 边界条件
int pre = nums[0];
int answer = nums[0];
for(int i = 1; i < nums.size(); i++) {
pre = max(pre + nums[i], nums[i]);
answer = max(answer, pre);
}
return answer;
}
};
go
// go
func maxSubArray(nums []int) int {
if len(nums) == 0 {
return 0
}
// 边界条件
pre := nums[0]
answer := nums[0]
for i := 1; i < len(nums); i++ {
pre = max(pre + nums[i], nums[i])
answer = max(answer, pre)
}
return answer
}
func max(a, b int) int {
if a > b {
return a
}
return b
}