题目:最大子序和:simple
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),
返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
package leetCode.DP;
public class lc_dp_53_maxSubArray {
/*
思路:
1)暴力: O(n^2)
2)dp: O(n)
*/
public static void main(String[] args) {
lc_dp_53_maxSubArray m = new lc_dp_53_maxSubArray();
int[] a = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
int res = m.maxSubArray(a);
System.out.println(res);
}
/*
dp:O(n)
1.状态
状态的定义非常重要!!
dp[i]:以索引i字符为结尾的子数组,其最大的和。
最后一个数字以i数字结尾,而不是在i字符结尾的子数组中的任意一段
此时保存的每个dp[i]是以该i数字结尾的最大子数组和,最后一个dp[i]不一定是答案
2.转移方程
自己单独开始,还是利用上面一段的结果
1)如果dp[i-1]>0,dp[i]=dp[i-1]+num[i];
2)如果dp[i-1]<=0,dp[i]=num[i];
3.边界条件
i-1>=0
*/
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
dp[0] = nums[0];
int max = dp[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
if (dp[i] > max)
max = dp[i];
}
return max;
}
/*
暴力:O(n^2)
*/
public int maxSubArray_violence(int[] nums) {
if (nums == null || nums.length == 0)
return 0;
int max = nums[0];
int val;
for (int i = 0; i < nums.length; i++) {
val = 0;
for (int j = i; j < nums.length; j++) {
val += nums[j];
if (val > max)
max = val;
}
}
return max;
}
}