• 剑指offer 30. 连续子数组的最大和


    30. 连续子数组的最大和

    题目描述

    HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

    思路一:

    动态规划,dp[i] 表示 以A[i]结尾的最大连续子序列和

    设当序列以A[i] 结尾时的和最大,如果序列长度为 1 ,那么dp[i] = A[i],

    如果序列长度不为 1, 则序列和为 前面的和 加上 A[i] , 即dp[i] = dp[i - 1] +A[i]; 所以转移方程为: dp = max(A[i], dp[i - 1] + A[i]);

    其实最主要看 dp[i - 1] 是大于0 还是小于0, 如果大于0,那肯定要加上前面的序列,如果小于0,则不要前面的序列; 所以状态转移方程可以改为 : dp[i] = dp[i - 1] > 0 ? dp[i - 1] + A[i] : A[i];

    再改进后可以改为 dp[i] = Math.max(nums[i], nums[i] + dp[i-1]);

     1 class Solution {
     2     public int maxSubArray(int[] nums) {
     3         // 动态规划,使用一个dp数组,每个dp元素表示以当前元素为子数组的最后一个结点的最大和
     4         int len = nums.length;
     5         int[] dp = new int[len];
     6         dp[0] = nums[0];
     7         int max = dp[0];
     8         for(int i = 1; i < len; i++){
     9             // 如果加上前面的子数组和比当前元素大,那么加上前面的子数组和,否则不加
    10             dp[i] = Math.max(nums[i], nums[i] + dp[i-1]);
    11             max = Math.max(max, dp[i]);
    12         }
    13         return max;
    14     }
    15 }

    leetcode运行时间为2ms,空间为45.2MB

    复杂度分析:

    时间复杂度:需要遍历一次数组,所以时间复杂度为O(n)

    空间复杂度:需要一个和nums数组等大的dp[]数组,所以空间复杂度为O(n)

    思路二

    对思路一的改进,仔细看思路一的代码,发现dp数组其实不需要的,只需要两个临时变量存储 dp[i]和dp[i-1]即可,所以代码可以修改为:

     1 class Solution {
     2     public int maxSubArray(int[] nums) {
     3         // 动态规划
     4         int len = nums.length;
     5         int pre = nums[0], cur = 0;
     6         int max = pre;
     7         for(int i = 1; i < len; i++){
     8             // 如果加上前面的子数组和比当前元素大,那么加上前面的子数组和,否则不加
     9             cur = Math.max(nums[i], nums[i] + pre);
    10             max = Math.max(max, cur);
    11             pre = cur;          // 更新子数组和
    12         }
    13         return max;
    14     }
    15 }

    leetcode运行时间为1ms, 空间为45.4MB

    复杂度分析:

    时间复杂度:同样需要遍历一遍数组,所以时间复杂度为O(n)

    空间复杂度:不需要临时的dp数组,所以空间复杂度为O(1)

  • 相关阅读:
    JDK API文档下载
    idea技巧:查看一个类的所有子类以及子类的子类并以层级关系显示
    Vue项目优化
    deepin 安装netcore 记录
    UOS 下的VScode 使用经验
    UOS操作系统磁盘空间不够一例
    SRPBatcher优化的原理
    我的UOS生活
    假如美国禁用了Unity3D和Unreal怎么办
    BGFX学习笔记01
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/12589314.html
Copyright © 2020-2023  润新知