[leetcode53]两种思路解决的Maximun Subarray
2017-03-04 15:15
302 查看
一、原题题干以及样例输出
Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array
contiguous subarray
=
这道题题意非常清楚,对于一个给定的整数型数组,计算其中和最大的子数组并将和输出结果。第一反应是动态规划的算法,思路简单,实现起来也不复杂,可能也为评级为easy级别原因所在。由于这周刚学了分治算法的思想,将其与分治算法联系起来,发现并不如动态规划那么容易处理,但将思路理清后,也将其实现。现在把问题的两种解决思路以及代码阐释如下。
二、动态规划算法解决
动态规划算法的原理很简单,在一个循环的过程中,不断地比较新产生的值与原来的值大小,若符合要求,则更新新值,否则原值
保持不变或者作另外处理。当这种思想与这题结合起来时,实现就非常清晰。在一个循环中,将初始和设置为0,若然后不断向量中的
值相加,并将旧值付给另外变量存储。若新相加的和比原来的和要大,则将和更新为新产生的值,若相加的值比0要小,则将和初始化
为0。遍历向量中的每一个元素,直到最后选出所得最大值的和。其代码实现如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum=nums[0];
int value=0;
if(nums[0]>0){
value=nums[0];
}
for(int i=1;i<nums.size();i++)
{
value+=nums[i];
if(value>sum){
sum=value;
}
if(value<0){
value=0;
}
}
return sum;
}
}; 三、分治算法解决最大和问题
分治算法的一个主要思路就是将一个长向量分割为几个长度更小的向量,然后在范围更小的向量里面解决问题,如此循环,直
至向量的长度至最小,那么解决问题时也就显得非常轻松了。这种算法好处非常明显,在某些环境下可以很好的减少时间复杂度以
及空间复杂度。在此题的情况下,使用分治算法就显得略为复杂。
首先是明确思路,对于一个向量,我们将其分为两个部分,那么最终最大和数组所分布的情况只有三种,一种是全部在向量的
左半边,一种是完全在向量的右半边,还有一种是即在左半边又在右半边,第三种情况肯定会覆盖向量中的中位值。有了这个前提
后,我们就可以分别计算出这三种情况的最大值,三个最大值中最大的那个也就是我们所需要输出的那个了。第一种和第二种情况
比较好计算,直接从最左端和最右端开始即可,对于第三种情况,可以先从中间向左计算最大值以及中间向右计算最大值,两者相
加后则为第三种情况的值。
那么将一个向量进行循环递归,不断分割成小向量,然后在最终的小向量中按照上诉方法去计算三个值并比较将最大的值作为
输出结果返回即可,具体实现如下:
public class Solution {
public int maxSum(int[] A, int left, int right )
{
if( left == right ){
return A[left];
}
int center = (left + right) / 2;
int maxLeftSum = maxSum( A, left, center);
int maxRightSum = maxSum( A, center+1, right);
int maxLeft = Integer.MIN_VALUE, tempLeft = 0;
int maxRight = Integer.MIN_VALUE, tempRight = 0;
for (int i=center; i>=left; --i){
tempLeft += A[i];
if (tempLeft > maxLeft){
maxLeft = tempLeft;
}
}
for (int i=center+1; i<=right; ++i){
tempRight += A[i];
if (tempRight > maxRight){
maxRight = tempRight;
}
}
int maxCenterSum = maxLeft + maxRight;
return maxCenterSum > maxLeftSum ? (maxCenterSum > maxRightSum ? maxCenterSum : maxRightSum) : maxLeftSum > maxRightSum ? maxLeftSum : maxRightSum;
}
public int maxSubArray(int[] A){
int len = A.length;
return maxSum(A,0,len-1);
}
}
四、个人总结
一般来说,分治算法解决问题大都会降低问题的时间复杂度,因为也受到非常广泛的欢迎。其核心就是将一个问题的解决范围
不断缩小,当范围缩小后,问题解决相对变得更加容易些,每一层递归所得到的结果都会为下一次递归做出贡献,这样循环下来,
直到问题解决,时间复杂度也就相应降低很多了。
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.
这道题题意非常清楚,对于一个给定的整数型数组,计算其中和最大的子数组并将和输出结果。第一反应是动态规划的算法,思路简单,实现起来也不复杂,可能也为评级为easy级别原因所在。由于这周刚学了分治算法的思想,将其与分治算法联系起来,发现并不如动态规划那么容易处理,但将思路理清后,也将其实现。现在把问题的两种解决思路以及代码阐释如下。
二、动态规划算法解决
动态规划算法的原理很简单,在一个循环的过程中,不断地比较新产生的值与原来的值大小,若符合要求,则更新新值,否则原值
保持不变或者作另外处理。当这种思想与这题结合起来时,实现就非常清晰。在一个循环中,将初始和设置为0,若然后不断向量中的
值相加,并将旧值付给另外变量存储。若新相加的和比原来的和要大,则将和更新为新产生的值,若相加的值比0要小,则将和初始化
为0。遍历向量中的每一个元素,直到最后选出所得最大值的和。其代码实现如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum=nums[0];
int value=0;
if(nums[0]>0){
value=nums[0];
}
for(int i=1;i<nums.size();i++)
{
value+=nums[i];
if(value>sum){
sum=value;
}
if(value<0){
value=0;
}
}
return sum;
}
}; 三、分治算法解决最大和问题
分治算法的一个主要思路就是将一个长向量分割为几个长度更小的向量,然后在范围更小的向量里面解决问题,如此循环,直
至向量的长度至最小,那么解决问题时也就显得非常轻松了。这种算法好处非常明显,在某些环境下可以很好的减少时间复杂度以
及空间复杂度。在此题的情况下,使用分治算法就显得略为复杂。
首先是明确思路,对于一个向量,我们将其分为两个部分,那么最终最大和数组所分布的情况只有三种,一种是全部在向量的
左半边,一种是完全在向量的右半边,还有一种是即在左半边又在右半边,第三种情况肯定会覆盖向量中的中位值。有了这个前提
后,我们就可以分别计算出这三种情况的最大值,三个最大值中最大的那个也就是我们所需要输出的那个了。第一种和第二种情况
比较好计算,直接从最左端和最右端开始即可,对于第三种情况,可以先从中间向左计算最大值以及中间向右计算最大值,两者相
加后则为第三种情况的值。
那么将一个向量进行循环递归,不断分割成小向量,然后在最终的小向量中按照上诉方法去计算三个值并比较将最大的值作为
输出结果返回即可,具体实现如下:
public class Solution {
public int maxSum(int[] A, int left, int right )
{
if( left == right ){
return A[left];
}
int center = (left + right) / 2;
int maxLeftSum = maxSum( A, left, center);
int maxRightSum = maxSum( A, center+1, right);
int maxLeft = Integer.MIN_VALUE, tempLeft = 0;
int maxRight = Integer.MIN_VALUE, tempRight = 0;
for (int i=center; i>=left; --i){
tempLeft += A[i];
if (tempLeft > maxLeft){
maxLeft = tempLeft;
}
}
for (int i=center+1; i<=right; ++i){
tempRight += A[i];
if (tempRight > maxRight){
maxRight = tempRight;
}
}
int maxCenterSum = maxLeft + maxRight;
return maxCenterSum > maxLeftSum ? (maxCenterSum > maxRightSum ? maxCenterSum : maxRightSum) : maxLeftSum > maxRightSum ? maxLeftSum : maxRightSum;
}
public int maxSubArray(int[] A){
int len = A.length;
return maxSum(A,0,len-1);
}
}
四、个人总结
一般来说,分治算法解决问题大都会降低问题的时间复杂度,因为也受到非常广泛的欢迎。其核心就是将一个问题的解决范围
不断缩小,当范围缩小后,问题解决相对变得更加容易些,每一层递归所得到的结果都会为下一次递归做出贡献,这样循环下来,
直到问题解决,时间复杂度也就相应降低很多了。
相关文章推荐
- 两种回溯方法解决子集问题的思路 leetcode 78. Subsets
- hdu2571 简单dp的两种解决思路
- [Unity3d][NGUI]两种思路解决AssetBundle的依赖关系.
- [LeetCode] Maximun Subarray
- LeetCode 53: Maximum Subarray
- [LeetCode]: 53: Maximum Subarray
- div中加入span右对齐后出现换行显示两种解决思路
- [LeetCode] 35. Search Insert Position 解决思路
- WebGIS中解决使用Lucene进行兴趣点搜索排序的两种思路
- LeetCode 53/152 Maximum Subarray/Maximum Product Subarray---DP **
- [LeetCode] Maximum Product Subarray 解题思路
- [Unity3d][NGUI]两种思路解决AssetBundle的依赖关系.
- Median of Two Sorted Arrays[leetcode] O(nlogn)的两种思路
- leetcode 之 Flatten Binary Tree to Linked List 解决思路
- LeetCode(53) Maximum Subarray
- div中加入span右对齐后出现换行显示两种解决思路(同行显示,一个居中,一个靠右)
- LeetCode 之 LRU Cache解决思路
- Jump Game II [leetcode] DP的两种思路
- Reorder List [leetcode] 这两种思路
- [LeetCode] Minimum Size Subarray Sum 解题思路