首页 > 其他分享 >53. 最大子数组和

53. 最大子数组和

时间:2023-04-21 19:34:50浏览次数:31  
标签:return 最大 nums int mid 53 数组 dp left

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

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

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

> 解法一(贪心)

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int result = INT32_MIN;
        int count = 0;
        for (int i = 0; i < nums.size(); i++) {
            count += nums[i];
            if (count > result) { // 取区间累计的最大值(相当于不断确定最大子序终止位置)
                result = count;
            }
            if (count <= 0) count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
        }
        return result;
    }
};

> 解法二(动态规划)

class Solution {
public:
    //状态转移方程为    dp[i] = max(dp[i - 1] + nums[i], nums[i])
    //  其中dp[i]表示以nums[i]结尾的最大子序列的值
    int maxSubArray(vector<int>& nums) {
        vector<int> dp(nums.size(),0);
        dp[0] = nums[0];
        int result = dp[0];
        for(int i = 1;i < nums.size(); i++){
            dp[i] = std::max(dp[i-1]+nums[i],nums[i]);
            if(result < dp[i]) result = dp[i];
        }
        return result;
    }
};

> 解法三(分治法)

class Solution {
public:
    int maxSubArray(vector<int> &nums) {
        int len = nums.size();
        if (len == 0) {
            return 0;
        }
        return maxSubArraySum(nums, 0, len - 1);
    }
private:
    int maxCrossingSum(vector<int> &nums, int left, int mid, int right) {
        // 一定会包含 nums[mid] 这个元素
        int sum = 0;
        int leftSum = INT32_MIN;
        // 左半边包含 nums[mid] 元素,最多可以到什么地方
        // 走到最边界,看看最值是什么
        // 计算以 mid 结尾的最大的子数组的和
        for (int i = mid; i >= left; i--) {
            sum += nums[i];
            if (sum > leftSum) {
                leftSum = sum;
            }
        }
        sum = 0;
        int rightSum = INT32_MIN;
        // 右半边不包含 nums[mid] 元素,最多可以到什么地方
        // 计算以 mid+1 开始的最大的子数组的和
        for (int i = mid + 1; i <= right; i++) {
            sum += nums[i];
            if (sum > rightSum) {
                rightSum = sum;
            }
        }
        return leftSum + rightSum;
    }

    int maxSubArraySum(vector<int> &nums, int left, int right) {
        if (left == right) {
            return nums[left];
        }
        int mid = left + (right - left) / 2;
        return max3(maxSubArraySum(nums, left, mid),
                maxSubArraySum(nums, mid + 1, right),
                maxCrossingSum(nums, left, mid, right));
    }

    int max3(int num1, int num2, int num3) {
        return std::max(num1, std::max(num2, num3));
    }
};

标签:return,最大,nums,int,mid,53,数组,dp,left
From: https://www.cnblogs.com/lihaoxiang/p/17341504.html

相关文章

  • ZigBee CC2530 定时器1中断
    #ZigBeeCC2530定时器1中断这段时间做一个智能家居的项目,用到ZigBee芯片,自然想到用CC2530。今天分享一个很简单的,通过按键控制定时器开启关闭,定时器中断函数里控制LED闪烁。#include<ioCC2530.h>#defineuintunsignedint#defineucharunsignedchar#defineLED1P1......
  • C# 数组输出拼接字符串以及拼接字符串转数组
    staticvoidTest(){int[]arr=newint[]{1,2,3,4,5,6};stringstr=string.Join(",",arr);//数组转拼接字符串int[]arr_new=Array.ConvertAll(str.Split(','),p=>Convert.ToInt32(p));......
  • 剑指 Offer II 005. 单词长度的最大乘积
    题目链接:剑指OfferII005.单词长度的最大乘积方法:转化为二进制位+位运算解题思路将\(words[i]\)字符串中包含的字母转换为二进制位上的\(1\),字符'a'对应二进制中的第\(0\)位上的\(1\),这样每个字符串就对应一个二进制数。通过两个字符串的二进制数进行'&'运算,......
  • 字节数组的理解
    一个字节占8位,即8个bit;一个字是两个字节;十六进制中的每一位占4bit,所以十六进制中的两位就占8bit,即一字节; java中字节数组的初始化byte[]asBytes=newbyte[]{(byte)0x00,(byte)0x02,(byte)0x00,(byte)0x00,(byte)0x10,(byte)0x00,(byte)0x20,(byte)0x......
  • Aras学习笔记 (53) - 根据ID快速找到文件Vault路径
    Step1:首先在对象类File中根据名称找到ID;Step2:右键文件-->Share-->CopyID;Step3:在Console中输入下命令:top.aras.IomInnovator.getFileUrl("[文件ID]",top.aras.Enums.UrlType.SecurityToken)结果如下: ......
  • JS的对象比较,JS的数组比较
    1数组对比一、toString()当两个数组元素类型相同,顺序相同时,直接判断是否相等,结果不相等;转化为字符串后,结果相等[1,2,3].toString()===[1,2,3].toString();//true[1,2,3].toString()===['1',2,3].toString();//true二、join()[1,2,3,'4'].join()===[1,2,3,......
  • 数组的常用方法
    数组的常用方法数组是一个复杂数据类型,我们在操作它的时候就不能再想基本数据类型一样操作了比如我们想改变一个数组//创建一个数组vararr=[1,2,3]//我们想把数组变成只有1和2arr=[1,2]这样肯定是不合理,因为这样不是在改变之前的数组相当于心弄了一个......
  • 二维数组遍历
    publicstaticvoidmain(String[]args){int[][]arr={{11,22,33},{44,55,66}};printArray(arr);intsum=getSum(arr);System.out.println("求和累加为:"+sum);}/*二维数组......
  • HDU 5389 Zero Escape(DP + 滚动数组)
    ZeroEscapeTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:131072/131072K(Java/Others)TotalSubmission(s):864    AcceptedSubmission(s):438ProblemDescriptionZeroEscape,isavisualnoveladventurevideogamedirectedbyKotar......
  • 树状数组解决逆序对问题c++
    前言在算法竞赛中,求逆序对是一个常见的问题。逆序对是指在一个数列中,如果存在,且,那么就是一个逆序对。例如,数列中的逆序对有,总共有树状数组树状数组(FenwickTree)是一种高效的数据结构,用于维护数列的前缀和。树状数组的主要优势在于可以快速对数列进行单点更新和区间查询,时间......