首页 > 其他分享 >LeetCode HOT 100:最大子数组和

LeetCode HOT 100:最大子数组和

时间:2022-12-19 22:55:14浏览次数:64  
标签:结尾 nums int HOT 数组 ans 100 LeetCode dp

题目:53. 最大子数组和

题目描述:

给你一个整数数组,在该数组的所有子数组中,找到一个子数组中所有元素相加和最大,返回这个最大的和。子数组就是一个数组中,由一个或几个下标连续的元素,组成的小数组,就叫原数组的子数组

思路:

这种求子数组怎么怎么的问题,都可以向一种思维上靠拢。即以某一个元素为结尾的子数组中,得到一个结果。然后以每一个元素都作为结尾,得到很多个结果,然后在这些结果中进行处理,一定得到正确的结果。
以本题举个例子:数组[-2,1,-3],先将每一个元素作为结尾的子数组的最大和求出来。

  • -2作为子数组结尾,只有[-2]一个子数组,最大和为-2
  • 1作为子数组结尾,有[-2,1][1]两个子数组,最大和为1
  • -3作为子数组结尾,有[-2,1,-3][1,-3][-3]三个子数组,最大和为-2

所以这道题将所有结果进行比较大小,一定找到一个正确结果为1。因为正确的答案一定是由某一个元素结尾的子数组得出来的。所以找到每一个元素结尾的子数组的结果,然后进行处理,一定得到正确结果。这种思维需要培养,遇到子数组怎么怎么的问题,看能不能尽量往这上面靠拢。
下面继续说这道题,还是举例数组[-2,1,-3],我们既然确定了方向,要获得以每一个元素结尾的子数组的最大和,最终将这些结果再取最大值。那么可以将这个问题拆分成几个小问题:

  • 子问题 1:以−2结尾的子数组的最大和是多少;
  • 子问题 2:以1结尾的子数组的最大和是多少;
  • 子问题 3:以−3结尾的子数组的最大和是多少;

我们单独看子问题 1 和子问题 2:
子问题 1:以−2结尾的子数组的最大和是多少;
−2结尾的子数组是[-2],因此最大和就是−2
子问题 2:以1结尾的子数组的最大和是多少;
1结尾的子数组有[-2,1][1],其中[-2,1]就是在「子问题 1」的后面加上1得到。−2+1=−1<1,因此「子问题 2」 的答案是1
大家发现了吗,如果编号为i的子问题的结果是负数或者0 ,那么编号为i + 1的子问题就可以把编号为i的子问题的结果舍弃掉,这是因为:
一个数a加上负数或0的结果不可能比a更大;
而子问题的定义必须以一个数结尾,因此如果子问题i的结果是负数或者0,那么子问题i + 1的答案就是原数组i下标的那个数,因为前面的和被舍弃了。

步骤:

1、定义dp数组,表示以nums[i]结尾的子数组的最大和
2、遍历数组,根据上述思路,完善dp数组,并不断更新最大和
3、返回最大和

代码:

    public int maxSubArray(int[] nums) {
        // dp[i] 表示:以 nums[i] 结尾的连续子数组的最大和
        int[] dp = new int[nums.length];
        dp[0] = nums[0];

        int ans = nums[0];
        for (int i = 1; i < nums.length; i++) {
            if (dp[i - 1] > 0) {
                dp[i] = dp[i - 1] + nums[i];
            } else {
                dp[i] = nums[i];
            }

            // 更新最大值
            ans = Math.max(ans, dp[i]);
        }

        return ans;
    }

空间优化代码:

    // 因为dp[i]只和dp[i - 1]有关,所以可以优化空间
    public int maxSubArray(int[] nums) {
        int pre = nums[0];
        int ans = nums[0];

        for (int i = 1; i < nums.length; i++) {
            if (pre > 0) {
                pre = pre + nums[i];
            } else {
                pre = nums[i];
            }

            ans = Math.max(ans, pre);
        }

        return ans;
    }

标签:结尾,nums,int,HOT,数组,ans,100,LeetCode,dp
From: https://www.cnblogs.com/yuhang-wiki/p/16993267.html

相关文章

  • LeetCode 102_二叉树的层序遍历
    LeetCode102:二叉树的层序遍历题目给你二叉树的根节点root,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。示例1:输入:root=[3,9,20,null,null,15,7]......
  • [C++]LeetCode 2502 设计内存分配器
    [C++]LeetCode2502.设计内存分配器题目描述Difficulty:中等RelatedTopics:设计,数组,哈希表,模拟给你一个整数n,表示下标从0开始的内存数组的大小。所有内存......
  • [C++]LeetCode 1971 寻找图中是否存在路径
    [C++]LeetCode1971.寻找图中是否存在路径题目描述Difficulty:简单RelatedTopics:深度优先搜索,广度优先搜索,并查集,图有一个具有n个顶点的双向图,其中每个......
  • Leetcode 169-多数元素
    Leetcode169-多数元素给定一个大小为n的数组 nums,返回其中的多数元素。多数元素是指在数组中出现次数大于 ⌊n/2⌋ 的元素。你可以假设数组是非空的,并且给定的数......
  • [LeetCode]008-字符串转换整数(atoi)
    >>>传送门题目请你来实现一个 myAtoi(strings) 函数,使其能将字符串转换成一个32位有符号整数(类似C/C++中的atoi函数)。函数 myAtoi(strings)的算法如下:读......
  • #yyds干货盘点# LeetCode程序员面试金典:动物收容所
    题目:动物收容所。有家动物收容所只收容狗与猫,且严格遵守“先进先出”的原则。在收养该收容所的动物时,收养人只能收养所有动物中“最老”(由其进入收容所的时间长短而定)的动物......
  • LeetCode 两数之和,三数之和,最接近的三数之和,四数之和(C++)
    1.两数之和问题描述给定一个整数数组​​nums​​​和一个目标值​​target​​,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。你可以假设每种输入......
  • LeetCode 有关二叉树的算法题目(C++)
    0、NULL与nullptr的区别在C语言中,​​NULL​​​通常被定义为:​​#defineNULL((void*)0)​​​。因为在C语言中把空指针赋给​​int​​​和​​char​​​指针的时候,发......
  • [leetcode]第 2 天 链表(简单)
    06.从尾到头打印链表思路说到从尾到头,很容易想到可以用到栈的方式进行处理,那么问题就转化成了如何用辅助栈完成打印链表。可以从链表的头节点开始,依次将每个节点压入栈......
  • [LeetCode] 1971. Find if Path Exists in Graph
    Thereisa bi-directional graphwith n vertices,whereeachvertexislabeledfrom 0 to n-1 (inclusive).Theedgesinthegrapharerepresentedasa......