• 牛客剑指offer刷题动态规划篇


    连续子数组的最大和

    题目

    给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

    子数组是数组中的一个连续部分。

    示例 1:

    输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
    输出:6
    解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
    示例 2:

    输入:nums = [1]
    输出:1
    示例 3:

    输入:nums = [5,4,-1,7,8]
    输出:23
    LeetCode链接

    思路

    以nums = [-2,1,-3,4,-1,2,1,-5,4]数据为例
    采用动态规划的思想,将以上问题转化为如下子问题:

    1. 求以-2结尾的连续子数组的最大值;
    2. 求以1结尾的连续子数据的最大值;
    3. 求以-3结尾的连续子数组的最大值;
    4. 求以4结尾的连续子数组的最大值;
    5. 求以-1结尾的连续子数组的最大值;
    6. 求以2结尾的连续子数组的最大值;
    7. 求以1结尾的连续子数组的最大值;
    8. 求以-5结尾的连续子数组的最大值;
    9. 求以4结尾的连续子数组的最大值;
      然后求以上子问题的最大值,即为所得结果;

    我们这里再求子问题2:求以1结尾的连续子数据的最大值;
    那对应的子数组只有2组,分别为[-2,1]和[1],很明显最大值数组为后者,那对应到公式应该为
    Math.max(prev + num[i],num[i]),其中prev表示以-2结尾的连续子数组的最大值,num[i]对应当前下标值;
    更加详细讲解可参考:LeetCode 经典动态规划问题

    代码实现
       public int maxSubArray(int[] nums) {
            if(nums == null || nums.length == 0){
                return 0;
            }
            int prev = 0;
            int result = nums[0];
            for(int num:nums){
                prev = Math.max(prev + num,num);
                result = Math.max(prev,result);
            }
          
            return result;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    连续子数组的最大和(二)

    题目

    描述
    输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,找到一个具有最大和的连续子数组。
    1.子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
    2.如果存在多个最大和的连续子数组,那么返回其中长度最长的,该题数据保证这个最长的只存在一个
    3.该题定义的子数组的最小长度为1,不存在为空的子数组,即不存在[]是某个数组的子数组
    4.返回的数组不计入空间复杂度计算

    示例1
    输入:
    [1,-2,3,10,-4,7,2,-5]
    返回值:
    [3,10,-4,7,2]
    说明:
    经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18,故返回[3,10,-4,7,2]

    示例2
    输入:
    [1]
    返回值:
    [1]

    示例3
    输入:
    [1,2,-3,4,-1,1,-3,2]
    返回值:
    [1,2,-3,4,-1,1]
    说明:
    经分析可知,最大子数组的和为4,有[4],[4,-1,1],[1,2,-3,4],[1,2,-3,4,-1,1],故返回其中长度最长的[1,2,-3,4,-1,1]

    思路

    和上题整体思路一致,只不过需要在计算子问题的过程中,把子问题解对应的数组开始下标和结束下标记录下来;

    代码实现
    public int[] FindGreatestSumOfSubArray (int[] array) {
            if(array == null || array.length == 0){
                return new int[0];
            }
            int[] dp = new int[array.length];
            dp[0] = array[0];
            int max = dp[0];
            //start end表示所求数组开始与结束下标
            int start = 0;
            int end = 1;
            //当前一个子问题的最大值小于0时,需要重置开始位置,负责记录开始问题
            int temp = 0;
            for(int i = 1;i<array.length;i++){
                if(dp[i-1] <  0){
                    dp[i] = array[i];
                    temp = i;
                }else{
                    dp[i] = dp[i-1]+array[i];
                }
              
                if(dp[i] >= max){
                    max = dp[i];
                    start = temp;
                    end = i+1;
                }
            }
            
            return Arrays.copyOfRange(array,start,end);
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    前台主页搭建、后台主页轮播图接口设计、跨域问题详解、前后端互通、后端自定义配置、git软件的初步介绍
    数据结构--图
    MySQL中 JOIN关联查询的原理以及优化手段
    不同相机在不同高度拍的图片resize在同一尺度
    牛客NC233 加起来和为目标值的组合(四)【中等 DFS C++、Java、Go、PHP】
    通俗易懂Java内存模型详解面试带例子
    MYSQL中的JDBC操作
    Nginx反向代理详解
    链接元宇宙,开启新纪元
    Qt开源工业软件收录
  • 原文地址:https://blog.csdn.net/a734474820/article/details/134506255