leetcode 52:Maximum Subarray
2015-11-16 20:59
288 查看
题目:
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array
the contiguous subarray
click to show more practice.
More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
思路:
首先想到的是用动态规划来做,因为动态规划跟前面计算的结果有关。
所以,对于给定的数组nums,我们可以定义一个相同大小的数组DP来存储当前元素对应的最大的连续元素之和。
以[−2,1,−3,4,−1,2,1,−5,4]举例分析。
当i=0时,DP[i]=-2;
当i=1时,DP[i]=1;
当i=2时,DP[i]=-2;
当i=3时,DP[i]=4;
......
很容易得出DP的递推式如下:
DP[i]=max(DP[i-1]+nums[i],nums[i]);
DP中最大值即为最后的返回值。
时间复杂度:O(n);
实现如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size = nums.size();
int maxSum = nums[0];
vector<int> DP(size, 0);
DP[0] = nums[0];
for (int i = 1; i < size; i++)
{
DP[i] = max(DP[i - 1] + nums[i], nums[i]);
if (DP[i]>maxSum) maxSum = DP[i];
}
return maxSum;
}
};
下面针对more practice,用分而治之的方法求解(参考:算法导论):
分治策略是将数组分成两个规模尽可能相等的子数组,然后求解两个子数组。
但是最大子数组有可能出现在以下几种情况中:
完全位于子数组nums[low...mid]中;
完全位于子数组nums[mid...high]中;
跨越了中点;
因此我们需在上面三种情况中找最大者。
时间复杂度:O(nlgn)
实现如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size = nums.size();
if (size == 1) return nums[0];
return FindMaximumSubArray(nums,0,size-1);
}
private:
int FindMaxCrossingSubArray(vector<int>& nums, int low, int mid, int high)
{
int leftSum = -0XFFFF, rightSum = -0XFFFF, tempSum = 0;
for (int i = mid; i >= low; i--)
{
tempSum += nums[i];
if (tempSum > leftSum) leftSum = tempSum;
}
tempSum = 0;
for (int i = mid + 1; i <= high; i++)
{
tempSum += nums[i];
if (tempSum > rightSum) rightSum = tempSum;
}
return leftSum + rightSum;
}
int FindMaximumSubArray(vector<int>& nums, int low, int high)
{
if (high == low) return nums[low];
int mid = (low + high) / 2;
int leftSum = FindMaximumSubArray(nums,low,mid);
int rightSum = FindMaximumSubArray(nums, mid+1, high);
int crossSum = FindMaxCrossingSubArray(nums, low, mid, high);
return max(max(leftSum, rightSum), crossSum);
}
};
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.
click to show more practice.
More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
思路:
首先想到的是用动态规划来做,因为动态规划跟前面计算的结果有关。
所以,对于给定的数组nums,我们可以定义一个相同大小的数组DP来存储当前元素对应的最大的连续元素之和。
以[−2,1,−3,4,−1,2,1,−5,4]举例分析。
当i=0时,DP[i]=-2;
当i=1时,DP[i]=1;
当i=2时,DP[i]=-2;
当i=3时,DP[i]=4;
......
很容易得出DP的递推式如下:
DP[i]=max(DP[i-1]+nums[i],nums[i]);
DP中最大值即为最后的返回值。
时间复杂度:O(n);
实现如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size = nums.size();
int maxSum = nums[0];
vector<int> DP(size, 0);
DP[0] = nums[0];
for (int i = 1; i < size; i++)
{
DP[i] = max(DP[i - 1] + nums[i], nums[i]);
if (DP[i]>maxSum) maxSum = DP[i];
}
return maxSum;
}
};
下面针对more practice,用分而治之的方法求解(参考:算法导论):
分治策略是将数组分成两个规模尽可能相等的子数组,然后求解两个子数组。
但是最大子数组有可能出现在以下几种情况中:
完全位于子数组nums[low...mid]中;
完全位于子数组nums[mid...high]中;
跨越了中点;
因此我们需在上面三种情况中找最大者。
时间复杂度:O(nlgn)
实现如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size = nums.size();
if (size == 1) return nums[0];
return FindMaximumSubArray(nums,0,size-1);
}
private:
int FindMaxCrossingSubArray(vector<int>& nums, int low, int mid, int high)
{
int leftSum = -0XFFFF, rightSum = -0XFFFF, tempSum = 0;
for (int i = mid; i >= low; i--)
{
tempSum += nums[i];
if (tempSum > leftSum) leftSum = tempSum;
}
tempSum = 0;
for (int i = mid + 1; i <= high; i++)
{
tempSum += nums[i];
if (tempSum > rightSum) rightSum = tempSum;
}
return leftSum + rightSum;
}
int FindMaximumSubArray(vector<int>& nums, int low, int high)
{
if (high == low) return nums[low];
int mid = (low + high) / 2;
int leftSum = FindMaximumSubArray(nums,low,mid);
int rightSum = FindMaximumSubArray(nums, mid+1, high);
int crossSum = FindMaxCrossingSubArray(nums, low, mid, high);
return max(max(leftSum, rightSum), crossSum);
}
};
相关文章推荐
- 浅谈swift中的那些类,结构以及初始化的操作
- www服务器架设linux+apache+mariadb+php
- Java excel的导入导出
- windows phone页面的简单导航操作
- Object-C之Protocol协议解析
- 《亲密关系》摘录
- Hadoop 1.x安装
- linux运维实战练习-2015年11月8日-11月17日课程作业(练习)汇总
- Android基础
- 看懂UML类图和时序图
- Lowest Bit
- Android APK反编译就这么简单 详解(附图)
- LightOJ 1007 Mathematically Hard
- ubuntu 安装新软件后利用export设计PATH重启依旧有效方法
- 定位-01-定位服务编程
- Android开发日记(一)
- ARC小结
- UWP 绘制图形
- 转载:警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting
- HDU 5525 Product