题目描述:
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
这道题刚开始没有思路,也没读懂题目的意思,最后,明白,就是这个数组中的元素组成的子序列的和最大就行,子序列至少包含一个元素。例如例子中,子序列可以为很多,但最大的是4,-1,2,1,和为6.
明白了题目什么意思,那么这道题就很明确了,自己的想法结合其他网友的解答,我总共总结除了三种思路。
先来看代码:
第一种方法:
int a[] = {-2,1,-3,4,-1,2,1,-5,4};
int sum = 0;
int num = a[0];
// 第一种方法,sum存储每一位相加时的和,num存储最终结果,与sum比较大的保存给num,小的,舍去.
for (int i=0;i0){
sum+=a[i];
}else
{
sum=a[i];
}
num = num>sum?num:sum;
}
System.out.println(num);
这种方法,就是遍历数组,然后当和大于0时就将元素相加,小于0时就将对应的i的值赋值给sum.这是什么意思呢?也就是说,在题目要求下,数组中出现负数对这个和是有影响的,当和为负数时,证明前面的元素都白相加了,那么就将此时对应的i赋值给sum,然后用另外一个变量保存最大的sum。最后输出。(用到三元运算符,当num大于sum时赋值num,否则赋值sum)
执行结果:
执行时间:
第二种方法:
/ 第二种方法
// 用来求和,当i所指的前一个元素大于0时,相邻两位相加,不相等是,保持不懂
for (int i = 1;i0){
a[i]=a[i]+a[i-1];
}
}
int max = a[0];
// 比较数组中的最大值,最大值即为所要求的和
for (int i=1;ia[i]?max:a[i];
}
System.out.println(max);
这种方法没有另外声明变量,只是用一个max变量保存最大的和。这个方法能比第一个好理解一点,就是,遍历数组,从第二个元素开始,当他的前一个元素大于0时,将这两个元素相加,赋值给i对应的元素,(因为负数对结果造成影响,所以当前一个元素为负数时,舍去。这个地方为什么要前一个元素不为负数时相加呢?这是因为数组从1开始遍历,第一个元素为i-1,遍历时会每个元素都会判断是否为负数。)然后得到的‘新的数组’,就是每一次比较相加的和,然后只需要遍历数组,判断新数组中的最大值,即为所要求的最大子序列的和。
执行时间:
第三种方法:
// 第三种方法,这个最好理解,就是一个用来存储结果,一个用来移动求和.
//先将sum定义为数组的第0个元素,如果sum加上第i(从1开始)个元素,
比第i个元素大,则将sum和第i个元素加起来,否则,将第i个元素赋值给sum(因为第i个元素都比元素和要大了,
则这个和就没用了,然后将新的大于这个和的值,赋值给sum.例如[-1,-2,4],计算到最后-2+4的和小于4了,
那么将4赋值给sum就是最大的子序列和.)
// 然后一边移动相加得到sum,一边与(最终答案)num(也就是存储最大的那个sum值)比较,
小的舍弃,大的付给num.最后输出.
int num = a[0];
int sum = a[0];
for (int i = 1;ia[i]){
sum=sum+a[i];
}else {
sum = a[i];
}
// 存储最大sum值
if (num
这个方法和第一中很相似但又有点不相同,总结来说就是,定义两个变量都指向数组的第一个元素,然后判断sum和数组i对应元素相加是否大于i对应元素,不大于就将a[i]赋值给sum,大于就sum与a[i]相加。最后与num比较,保存最大的sum.输出即可。例如:【1,-2,-3,4】,sum=1.然后判断1-2>-2,则sum=-1,然后判断,num与sum谁大,num=1,以此类推,最后输出1.
也就是,判断和是否小于其中的元素,小于令sum=这个元素,大于时,就相加。
执行时间:
总结:这道题看似不太难,但其中的内涵还是很丰富的,有些地方,自己也没有想到。还是差很多,慢慢来继续行走
2019-1-31记录