您的位置:首页 > 其它

[Lintcode] Best Time to Buy and Sell Stock I, II, III && Maximum Subarray

2015-11-20 02:32 197 查看

买卖股票系列 && Subarray

相关题目:

Best Time to Buy and Sell Stock I && II && III (IV 单独开贴)

Maximum Subarray I && II

为什么这些我要总结到一起呢?因为思路基本一致。

题目简略:

买卖股票1: 一次买卖,利润最大。

买卖股票2: N次买卖,利润最大。

买卖股票3: 2次不重叠的买卖,利润最大。

Maximum Subarray: Given an array of integers, find a contiguous subarray which has the largest sum.

Maximum Subarray II: 两次分割, 求最大sum

不难看出,其实买卖股票1跟Maximum subarray是一个题,所以先来说说这个热身题。

Maximum Subarray:

Given an array of integers, find a contiguous subarray which has the largest sum.

Example

Given the array
[−2,2,−3,4,−1,2,1,−5,3]
, the contiguous subarray
[4,−1,2,1]
has the largest sum =
6
.

Note

The subarray should contain at least one number.

Challenge

Can you do it in time complexity O(n)?

SOLUTION:

最简单的思路,连续子数组有n^2个(开头的位置有n个可能,结尾也有n个可能,一共就是n^2个可能)。两个循环for 头,for尾,可以解决。

再来思考O(n)的方法:

这里已看到Subarray就一定要知道一个概念 prefix sum:前缀和,也就是prefix[i] = sum(A[0]~A[i]). 从prefix sum就可以转化到subarray sum,具体这样实现:

subarray[i, j] = prefix[j] - prefix[i - 1]

既然有这种方法,求最大值也就是说,对于一个固定点来说,找到之前prefix的最小值,就可能找到他们差值的最大值了。

代码:

public class Solution {
/**
* @param nums: A list of integers
* @return: An integer denotes the sum of max two non-overlapping subarrays
*/
public int maxTwoSubArrays(ArrayList<Integer> nums) {
int[] right = new int[nums.size()];
int[] left = new int[nums.size()];
int sum = 0;
int max = Integer.MIN_VALUE;
int minSum = 0;
for (int i = 0; i < nums.size(); i++){
sum = sum + nums.get(i);
max = Math.max(max, sum - minSum);
minSum = Math.min(minSum, sum);
left[i] = max;
}
sum = 0;
minSum = 0;
max = Integer.MIN_VALUE;
for (int i = nums.size() - 1; i >= 0; i--){
sum = sum + nums.get(i);
max = Math.max(max, sum - minSum);
minSum = Math.min(minSum, sum);
right[i] = max;
}
max = Integer.MIN_VALUE;
for (int i = 0; i < nums.size() - 1; i++){
max = Math.max(max, left[i] + right[i + 1]);
}
return max;
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: