题目描述:
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [-2,1,-3,4,-1,2,1,-5,4]
,
the contiguous subarray [4,-1,2,1]
has the largest sum = 6
.
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
我的思路:
题意就是求一个数组的子数组使得他的元素的加和达到最大,子数组中最少还有一个元素。
第一反应就是循环呗,外层是几个数的加和,内层用来在数组中循环。试了几个例子,通过了,但是提交的时候超时了。
题目底下也有提示,要求找一个O(n)的solution。也就是说循环一次,就完成计算。
sum用来保存加上当前元素的sum和当前元素的最大值,maxSum用来时刻保存sum的最大值。具体代码如下:
我的代码:
def maxSubArray(self, nums):
"""
第一遍写的,暴力搜索解法。。。超时
"""
if len(nums) == 1:
return nums[0]
rel = -99999999
for i in range(len(nums)):
for j in range(len(nums) - i):
sum, k = nums[j], i
while k > 0:
sum += nums[j + k]
k -= 1
rel = max(sum, rel)
return rel
def maxSubArray(self, nums):
"""
O(n)复杂度的解法
"""
sum = nums[0]
maxSum = nums[0]
for i in range(1, len(nums)):
sum = max(nums[i], sum + nums[i]) # sum用来保存加上当前元素的sum和当前元素的最大值。
maxSum = max(sum, maxSum) # maxSum用来时刻保存sum的最大值
return maxSum
Discuss:
练习中提到的分治法查看了discuss,找个java代码贴在这吧。
class Solution {
public:
int maxSubArray(int A[], int n) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(n==0) return 0;
return maxSubArrayHelperFunction(A,0,n-1);
}
int maxSubArrayHelperFunction(int A[], int left, int right) {
if(right == left) return A[left];
int middle = (left+right)/2;
int leftans = maxSubArrayHelperFunction(A, left, middle);
int rightans = maxSubArrayHelperFunction(A, middle+1, right);
int leftmax = A[middle];
int rightmax = A[middle+1];
int temp = 0;
for(int i=middle;i>=left;i--) {
temp += A[i];
if(temp > leftmax) leftmax = temp;
}
temp = 0;
for(int i=middle+1;i<=right;i++) {
temp += A[i];
if(temp > rightmax) rightmax = temp;
}
return max(max(leftans, rightans),leftmax+rightmax);
}
};
学到:
还是没有动态规划的思维,遇到题总是想暴力解决,还是要多动脑筋,想想问题的本质,发现其中的规律。