题目描述
给定一个整数数组,找出总和最大的连续数列,并返回总和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
- 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
解题思路与代码
-
首先,这道题是一道稍微有点难度的简单题。需要同学们对贪心算法思想与动态规划算法思想有一点基础的了解。做这道题就会非常的简单。
-
反之,可能会有点难。有可能你做出这道题后,你都不知道你使用的方法是贪心还是动态规划。
这道题题目的进阶说是可以使用分治算法去求解。我看了看,感觉实在是没有必要。因为,这只是道简单题。动态规划和贪心已经可以了。而分治呢,有一种舍近求远的感觉,还把这道题上升到了另一个高度。复杂度也比这两种的实现要高。所以,我真心觉得没有必要。所以也就不去做这个实现了。
方法一:贪心算法思想
- 我做这道题的时候,我先是假定这道题里面的数组里面的数字,是有正有负的一个序列。
- 那么我写的这个实现,前半部分就是试图在整个数组中,找到总和最大的连续数列,并返回总和。我用一个for循环与两个变量去实现这个算法。
- 在遍历数组过程中,每次都选择使得当前连续子数组和 count 大于零的元素。当遇到使得 count 之和小于零的元素时,就选择跳过这个元素,重新开始累加。
- 后来发现,这道题中,竟然有全都是负数的情况,那全都是负数我该怎么办呢?那当然是返回最小的那个负数了。
- 最后返回结果即可
具体代码如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int count = 0;
int result = 0;
for(int i = 0; i < nums.size(); ++i){
if(count + nums[i] < 0) {
count = 0;
continue;
}
count += nums[i];
result = max(count,result);
}
if(result == 0){
result = nums[0];
for(int i = 1; i < nums.size(); ++i)
result = max(result,nums[i]);
}
return result;
}
};
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)
方法二:优化:动态规划思想
- 相比与上一种的贪心算法思想,我觉得我这一种动态规划思想会使代码看的更有简介,并且效率更高。因为我优化掉了一个for循环。
- 这个算法的思路是,从数组的第二个元素开始遍历,每次更新 currNum 为当前元素与 currNum 加上当前元素的较大值。
- 这样一来,我们可以确保 currNum 始终是一个可能的连续子数组的和。
- 然后我们将 maxNum 更新为 currNum 和 maxNum 中的较大值,这样我们就可以在遍历过程中找到最大的连续子数组和。
具体代码如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int currNum = nums[0];
int maxNum = nums[0];
for(int i = 1; i < nums.size(); ++i){
currNum = max(nums[i],currNum + nums[i]);
maxNum = max(currNum,maxNum);
}
return maxNum;
}
};
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)
总结
这道题目(求最大连续子数组和)的意义在于:
-
算法设计思路:这道题目提供了一个平台,让我们可以学习和探讨不同的算法设计思路,例如贪心算法、动态规划和分治法。通过比较和分析这些方法的优缺点,我们可以更好地理解这些算法设计思路及其应用场景。
-
问题求解能力:解决这类问题可以锻炼我们的问题分析和解决能力。通过思考问题,我们学会将问题拆解成更小的子问题,然后寻找合适的方法将这些子问题的解合并成原问题的解。这种能力在实际编程工作中非常重要。
-
代码实现技巧:编写不同解法的代码可以提高我们的编程技巧。例如,在实现动态规划解法时,我们需要考虑状态的表示和状态转移方程;在实现分治法时,我们需要掌握递归的技巧以及如何合并子问题的解。这些技巧都是编程过程中必备的能力。
-
优化性能:这道题目也强调了优化算法性能的重要性。在实际应用中,我们往往需要在有限的时间和空间资源下求解问题。通过对比不同算法的时间复杂度和空间复杂度,我们可以更好地了解如何在实际问题中选择合适的算法。
总之,这道题目具有一定的教育意义和实际应用价值。通过学习和掌握这类问题的解决方法,我们可以提高自己的算法设计、问题求解和编程能力。
最后的最后,如果你觉得我的这篇文章写的不错的话,请给我一个赞与收藏,关注我,我会继续给大家带来更多更优质的干货内容
。