title: leetcode-55-最大子序和(java)
date: 2019-09-12 17:00:49
categories:
- leetcode
tags: - leetcode
最大子序和(java)
-
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-subarray
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 -
解:一遍遍历解决问题,寻找最大值
class Solution { public int maxSubArray(int[] nums) { int max = nums[0]; int sum = 0; for (int num:nums){ if(sum>0) sum+=num; else sum = num; max = Math.max(sum,max); } return max; } }
-
时间复杂度更低的方法:分治,原理就是对半开,不断的切切切
public class Solution { public int maxSubArray(int[] nums) { int len = nums.length; if (len == 0) { return 0; } return maxSubArraySum(nums, 0, len - 1); } private int maxCrossingSum(int[] nums, int left, int mid, int right) { // 一定会包含 nums[mid] 这个元素 int sum = 0; int leftSum = Integer.MIN_VALUE; // 左半边包含 nums[mid] 元素,最多可以到什么地方 // 走到最边界,看看最值是什么 // 计算以 mid 结尾的最大的子数组的和 for (int i = mid; i >= left; i--) { sum += nums[i]; if (sum > leftSum) { leftSum = sum; } } sum = 0; int rightSum = Integer.MIN_VALUE; // 右半边不包含 nums[mid] 元素,最多可以到什么地方 // 计算以 mid+1 开始的最大的子数组的和 for (int i = mid + 1; i <= right; i++) { sum += nums[i]; if (sum > rightSum) { rightSum = sum; } } return leftSum + rightSum; } private int maxSubArraySum(int[] nums, int left, int right) { if (left == right) { return nums[left]; } int mid = (left + right) >>> 1; return max3(maxSubArraySum(nums, left, mid), maxSubArraySum(nums, mid + 1, right), maxCrossingSum(nums, left, mid, right)); } private int max3(int num1, int num2, int num3) { return Math.max(num1, Math.max(num2, num3)); } }