Link to the topic : https://leetcode.cn/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/
1. Topic introduction (42. Maximum sum of consecutive subarrays)
Input an integer array, one or more consecutive integers in the array form a sub-array. Find the maximum of the sum of all subarrays.
The required time complexity is O(n).
[Test case]:
Example 1:
Input : nums = [-2,1,-3,4,-1,2,1,-5,4]
Output : 6
Explanation : The sum of consecutive subarrays [4,-1,2,1] is the largest, which is 6.
[Conditions]:
Tips :
- 1 <= arr.length <= 10^5
- -100 <= arr[i] <= 100
【Related Topics】:
Note : This question is the same as the main site [LeetCode] No.53. The largest sub-array sum – Java Version .
2. Solution
2.1 Enumeration – O(n 2 )
Time complexity O(n 2 ), space complexity O(1)
[ Problem-solving ideas ]:
Unresolved when things happen, violent enumeration, the most direct method,枚举数组的所有子数组
and find their sum. But I don’t know if it’s because I’ve been doing a lot of hard work recently. What I thought at the beginning was 1. Separate all sub-arrays first; 2. Traverse and compare all sub-arrays to find the largest.所有符合条件的子数组
It is more reasonable to use this method if the question requires return . If it is just like this question, the return is only the maximum value, which is true and unnecessary.
...
【Implementation strategy】:
- Define a double loop to loop through the possibility of each sub-array;
- Define the current cumulative sum variable
sum
and the maximum summaxSum
. Once the current cumulative sum is found to be greater than the maximum sum, modify the maximum sum to the cumulative sum;- The loop ends and the result is returned.
class Solution {
// Soulution1:枚举所有子数组和
public int maxSubArray(int[] nums) {
// 定义变量 n 记录数组长度
int n = nums.length;
// 定义变量 maxSum 记录最大子数组和
int maxSum = Integer.MIN_VALUE;
// 双重循环,依次遍历所有可能的子数组
for (int i = 0; i < n; i++)
{
int sum = 0;
for (int j = i; j < n; j++)
{
sum = sum + nums[j];
// 如果当前子数组的和大于 maxSum,则让其成为最大
if (sum > maxSum)
{
maxSum = sum;
}
}
}
// 最后返回结果
return maxSum;
}
}
2.2 Example to analyze the law of arrays (original solution 1) -- O(n)
Time complexity O(n), space complexity O(1)
[ Problem solving ideas ]:
Try to accumulate each number in the example array one by one from the beginning to the end , and initialize the sum to 0. The first step is to add the first number 1, and the sum is 1 at this time. Add the number -2 to the second part, and the sum becomes -1. The third step is to add the number 3. We noticed that since the previous accumulated sum is -1, which is less than 0, then if we add -1 to 3, the resulting sum is 2, which is smaller than 3 itself. Therefore, we don't consider subarrays starting from the first number, and the accumulated sums are also discarded.
By way of example, we can find the following rules:
- Start traversing and accumulating from the first element, if the accumulative sum is less than or equal to 0 (when a negative number is encountered, the accumulative sum is reduced), it means that the sub-array at this time must not be the largest, and it can be discarded;
- After discarding the previous cumulative sum, start again with the current value traversed until the traversal ends to obtain the maximum sum.
...
【Implementation strategy】:
- As shown in the idea of solving the problem, one traversal, when the current accumulated sum
sum
is less than or equal to 0, discard the previous accumulated sum and only assign it to the current number;- If the cumulative sum is greater than 0, let it continue to accumulate;
- In the process of traversal, once it is found that the current cumulative sum is greater than the maximum sum
maxSum
, the value of the maximum sum is modified to the current cumulative sum.
class Solution {
// Soulution2:一次遍历
public int maxSubArray(int[] nums) {
// 判断无效输入
if (nums.length <= 0) return -1;
// 定义变量 n 记录数组长度
int n = nums.length;
// 定义累加和 sum 与 最大和 maxSum
int sum = 0;
int maxSum = Integer.MIN_VALUE;
// 开始循环
for (int i = 0; i < n; i++){
// 如果当前 累加和 小于等于0,丢弃该值,重新开始
if (sum <= 0) sum = nums[i];
else sum += nums[i];
// 如果在循环的过程中出现了更大值,则修改最大和
if (sum > maxSum) maxSum = sum;
}
return maxSum;
}
}
2.3 Dynamic programming (original solution 2) -- O(n)
Time complexity O(n), space complexity O(1)
[ Problem-solving ideas ]:
About when to use DP?
- First of all, you have to understand
回溯法
, after all, itDP
is the origin of , after you are familiar with backtracking, you find that this question seems to be able to use backtracking, or you find that you want to traverse it to give an answer, but the answer does not require all the satisfied The solutions are all listed, but only a few solutions need to be given, which can generally be considered at this timeDP
....
as shown in the formula above:
- We can use the function
f(i)
to representi
the maximum sum of the sub-arrays ending with the number, then we need to find outmax[f(i)]
, among them0 <= i < n
.;i-1
When the sum of the numbers of the subarray ending with the th number is less than 0, add this negative number to the thi
number, and the result will be smaller than thei
th number itself, so in this case thei
subarray ending with the th number The array isi
the number itself;i-1
If the sum of the numbers in the subarray ending with the number is greater than 0, addingi
to the number gives the sum of all the numbers in the subarray ending with the number.i
...
[ Implementation strategy ]:
Dynamic programming belongs to the value of the latter state depending on the previous state, here, it isdp[i]
onlydp[i-1]
related to . In this question, the idea of dynamic programming is used to solve the problem. The code is almost the same as 2.2. In fact, it is to find the relationship, but the difficulty lies in how to find the recursive relationship from the previous .
class Solution {
public int maxSubArray(int[] nums) {
int count = nums.length;
int sum = nums[0],dp=nums[0];
for(int i = 1; i < count; i++)
{
if(dp > 0) dp += nums[i];
else dp = nums[i];
sum = Math.max(sum,dp);
}
return sum;
}
}
3. References
[1] Interview question 42. The maximum sum of continuous sub-arrays (dynamic programming, clear diagram)
[2] If you think of dp at the first time, write it in 1 minute
[3] Introduction to dynamic programming algorithm