C语言求解连续子数组的最大和(二)
-
解题思路: 由于已经使用动态规划解决了连续子数组的最大和(一),那么思路相同,只不过这次的输出是要求输出这个连续子数组,那么可以添加一个变量,用于记录返回数组的末尾元素位置,同时还需要一个变量记录一下连续的数组长度。
-
遇到的坑:
2.1 由于遇到多个最优解的字符串 返回最长的那个 这里的最长子数组有两种可能,一种是dp[i-1]=0,那么之后的序列可以包含dp[i-1]也可以从dp[i]开始,比如:1 2 -3 4 -1 1 -3 2,对应的dp数组为 1 3 0 4 3 4 1 3,可以看到最大值为4,并且有两个,最大数组分别是:[1,2,-3,4]或者是[4],那么怎么解决这个问题呢?这个问题的解决位于第25行 dp数组的构建时,当遇到dp[i-1]=0时仍然使得长度length++即可。第二种可能:1 2 3 -8 3 3的情况 有[1,2,3]和[3,3],这个问题的解决方式是在第34行,当比较最大dp值的时候,当dp相同,比较一下长度是否也变大了。
2.2 小细节:由于时间复杂度O(n),空间复杂度是O(1),在求连续子数组最大和(一)的基础上优化,由于dp数组并不是都需要用到,我只需要使用最大值来更新记录遍历的一个dp即可。空间复杂度为O(1)
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型一维数组
* @param arrayLen int array数组长度
* @return int整型一维数组
* @return int* returnSize 返回数组行数
*
* C语言声明定义全局变量请加上static,防止重复定义
*/
int* FindGreatestSumOfSubArray(int* array, int arrayLen, int* returnSize ) {
// 先写一个计算连续子数组最大和的dp解 只需要记录一下每个位置包含的元素个数
if(array==NULL||arrayLen==0)
return NULL;
if(arrayLen==1){
*returnSize=1;
return array;
}
int dphere=array[0];
int maxnum=array[0];
int loc=0;//记录最大值位置
int length=1;//记录连续数组的长度
int num_length=0;
for(int i=1;i<arrayLen;i++){
if(dphere+array[i]>=array[i]){
length++;
dphere=dphere+array[i];
}
else{
length=1;
dphere=array[i];
}
//如果最大值更新了 同时更新当前最大值的位置 以及子数组的长度
if(maxnum<=dphere||(maxnum==dphere&&length>num_length)){
loc=i;
num_length=length;
maxnum=dphere;
}
}
*returnSize=num_length;
return &array[loc-num_length+1];
}