华为OD面试手撕算法-最大子数组和

题目描述

本题是leetcode原题(中等难度):最大子数组和

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

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

思路分析

动态规划 】当前位置的子数组最大和可以由前一个位置的结果推理出来,即当前状态可由上一个状态推出,对于这一类问题,我们都可以考虑使用动态规划来解决【墙推Carl哥的代码随想录】。

DP五部曲分析:

1)确定dp数组的下标及含义:dp[i]表示以nums[i]结尾的连续子数组最大和

2)确定递推公式:当前位置的值只能由前一个位置dp[i-1]推出。对于dp[i-1],我们有两种选择:

① 若dp[i-1] < 0:表示前i-1个元素的最大子数组和小于0,说明其对当前位置的结果有负面作用,我们选择抛弃,从当前位置重新开始,此时dp[i] = nums[i];

② 若dp[i-1]>=0: 表示前i-1个元素的最大子数组和大于等于0,说明对当前位置结果有正向作用,我们选择接纳,此时dp[i] = dp[i-1] + nums[i];

故递推公式为dp[i] = max(nums[i],dp[i-1]+nums[i])

  1. 初始化dp:第一个位置的最大子数组和即为本身,故dp[0] = nums[0],其余元素均初始为0;

4)确定遍历顺序:dp[i] 是由dp[i-1]推出的,故遍历顺序为从前向后

5)举例验证dp过程

因为我们要求的是全局最大和,所以dp遍历过程中,应该用一个全局遍历记录最大值maxSum,最后返回maxSum。

代码实现

Go 复制代码
func maxSubArray(nums []int) int {
    maxSum := nums[0]
    dp := make([]int,len(nums))
    //dp初始化
    dp[0] = nums[0]
    for i := 1;i < len(nums);i++{
        dp[i] = maxVal(nums[i],dp[i-1]+nums[i])
        maxSum = maxVal(maxSum,dp[i])
    }
    return maxSum
}

func maxVal(a,b int) int{
    if a > b {
        return a
    }
    return b
}
相关推荐
biter down20 分钟前
C++ 解决海量数据 TopK 问题:小根堆高效解法
c++·算法
用户66006766853923 分钟前
斐波那契数列:从递归到缓存优化的极致拆解
前端·javascript·算法
初夏睡觉29 分钟前
P1055 [NOIP 2008 普及组] ISBN 号码
算法·p1055
程芯带你刷C语言简单算法题32 分钟前
Day28~实现strlen、strcpy、strncpy、strcat、strncat
c语言·c++·算法·c
shoa_top35 分钟前
一文带你掌握 JSONP:从 Script 标签到手写实现
前端·面试
知其然亦知其所以然37 分钟前
小米的奇幻编程之旅:当 JavaScript 语法变成了一座魔法城
前端·javascript·面试
Aniugel39 分钟前
Vue2怎么搭建前端性能/错误/行为监控体系
vue.js·面试·监控
踏浪无痕44 分钟前
周末拆解:QLExpress 如何做到不编译就能执行?
后端·算法·架构
一个不知名程序员www1 小时前
算法学习入门--- 树(C++)
c++·算法
如竟没有火炬1 小时前
四数相加贰——哈希表
数据结构·python·算法·leetcode·散列表