第一个问题是求一个数组的子数组的最大和:
这道题目比较简单,可作为第二道题的基准。
使用动态规划来做。
dp[i - 1] = max(dp[i - 1] + a[i],a[i])
代码如下
#include <iostream>
#include <algorithm>
using namespace std;
class Solution{
public:
int FindGreatestSumOfSubArray(vector<int> array){
vector<int> vec(array.size(),0);
int maxnumber = array[0];
vec[0] = array[0];
if(array.size() == 1) return array[0];
for(int i = 1;i < array.size();i ++){
vec[i] = max(vec[i - 1] + array[i],array[i]);
if(vec[i] > maxnumber) maxnumber = vec[i];
}
return maxnumber;
}
};
第二个问题是需要返回长度最长的最大和子数组:
使用一个start,end来确定一个检测区间,一旦有元素值大于前面检测区的最大值加上它自己的话,拿么就更新检测区到这个元素,将这个元素与前面所有元素分割开来,因为要想获得最大值,这个元素不可能和前面的元素组成数组。总的来说就是这个元素嫌前面相邻的队友,自己单干都比与他们合作的数值大。
为了弄明白这道题目:
首先,要想明白一个问题:
假设有一个检测区间内的局部最大值,其下标为i,那么i一定小于等于end(注意元素值可能为正可能为负)。并且当前检测区域的局部最大长度子数组一定为start到i。 我们可以把这个区间叫做局部最大区间,这个最大值叫做局部最大值(还有一个全局最大值,即问题一求的)
接下来:
由于end一直向后移动,那么局部最大值肯能会更新。那么我们在局部最大值更新时让它与全局最大值作比较,有三种情况:
若它比全局最大值小,就不用管。
若它比全局最大值大,则这个局部最大区间就是现在的全局最大区间了,那么把返回区间等于上这个全局最大区间就行了。
若它与全局最大值相等,那就再比较局部最大区间与全局最大区间的长度,那个长,那个就是全局最大区间(题目要求最长子数组)。
所以:
使用一个rstart,rend来确定一个返回区间:
一旦在检测区间内发现了最大值,就把自己更新到与检测区间相同。
因为要求最大长度,所以一旦在检测区间发现了等于当前最大值的值,并且检测区间的长度要大于当前返回区间的长度,则更新返回区间与检测区间相同。
代码如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型vector
* @return int整型vector
*/
vector<int> FindGreatestSumOfSubArray(vector<int>& array) {
if(array.size() <= 1) return array;
vector<int> dp(array.size(),0);
int maxNumber = array[0];
dp[0] = array[0];
int start = 0;
int end = 0;
int rstart = 0;
int rend = 0;
for(int i = 1;i < array.size();i ++){
//end指向当前元素
end ++;
//转移方程
dp[i] = max(dp[i - 1] + array[i],array[i]);
//Start将当前元素与之前数组分割开来,确定一个新的检测区域
if(array[i] > dp[i - 1] + array[i]){
start = end;
}
//检测区间内出现更大的值时,记录最大值,同时更新返回区间与检测区间相同
if(dp[i] > maxNumber){
maxNumber = dp[i];
rstart = start;
rend = end;
}
//检测区间内再次出现最大值,若长度比现在的返回区间要长,则更新返回区间
else if(dp[i] == maxNumber && (end - start) > (rend - rstart)){
rstart = start;
rend = end;
}
}
//返回返回区间即可
vector<int> res;
for(int i = rstart;i <= rend;i ++)
{
res.push_back(array[i]);
}
return res;
}
};
新手学习中,记录与分享我刷题的一些想法。大家请请多指正。