Leetcode题库-最大子序和(java语言版)

   题目描述: 

给定一个整数数组 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;i<a.length;i++){
            if (sum>0){
                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;i<a.length;i++){
            if (a[i-1]>0){
                a[i]=a[i]+a[i-1];
            }
        }
        int max = a[0];
//        比较数组中的最大值,最大值即为所要求的和
        for (int i=1;i<a.length;i++){
              max = max>a[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;i<a.length;i++){
//            移动i比较相加得sum
            if (sum+a[i]>a[i]){
                sum=sum+a[i];
            }else {
                sum = a[i];
            }
//            存储最大sum值
            if (num<sum){
              num=sum;
            }

        }
        System.out.println(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记录

发布了43 篇原创文章 · 获赞 6 · 访问量 6683

猜你喜欢

转载自blog.csdn.net/weixin_37850160/article/details/86728770