持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
1、前言
每天一个算法小练习,本篇使用Java实现。
2、题目描述
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。
- 1 <= nums.length <= 105
- -104 <= nums[i] <= 104
2.1、示例1
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
2.2、示例2
输入:nums = [1]
输出:1
2.3、示例3
输入:nums = [5,4,-1,7,8]
输出:23
3、解题思路
3.1、动态规划
这道题可以使用动态规划求最大连续子串来解决,首先定义一个长度为nums.length的数组,以dp[i]记录在i位置结束的连续子串的最大和,刚开始的dp[i]要定义为nums[0],因为此时的子数组就是num[0],自身值就是最大值。那么如果dp[i-1]<=0,则dp[i]就为nums[i]。反之,dp[i] = dp[i-1] + nums[i]。
class Solution {
public int maxSubArray(int[] nums) {
// nums = [-2,1,-3,4,-1,2,1,-5,4]
// dp = [-2,1,-2,4,3,5,6,1,5]
int length = nums.length;
int[] dp = new int[length];
dp[0] = nums[0];
int max = dp[0];
for (int i = 1; i < length; i ++) {
// 判断是否需要更新局部最大数
if (dp[i-1] < 0) {
dp[i] = nums[i];
} else {
dp[i] = nums[i] + dp[i-1];
}
if (dp[i] > max) {
// 判断是否需要更新历史最大数
max = dp[i];
}
}
return max;
}
}
-
时间复杂度:,N为数组的长度。因为我们只需要遍历一次数组即可。
-
空间复杂度:。
执行结果:
当然,我们还可以在优化下,不去new dp 数组,进一步优化空间复杂度。
class Solution {
public int maxSubArray(int[] nums) {
int length = nums.length;
int dp = nums[0];
int max = nums[0];
for (int i = 1; i < length; i ++) {
if (dp < 0) {
dp = nums[i];
} else {
dp += nums[i];
}
if (dp > max) {
max = dp;
}
}
return max;
}
}
执行结果:
从提交结果来看,优化后执行结果有了很大提升。(优化后空间复杂度为)
好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊