《剑指Offer》- 连续子数组的最大和或最小和

简介: 本文是《剑指Offer》系列(JavaScript版)的第一篇,题目是“连续子数组的最大和或最小和”。

前言


本文是《剑指Offer》系列(JavaScript版)的第一篇,题目是“连续子数组的最大和或最小和”。


话不多说,开始“打怪”修炼...


一、理解题目


以“连续子数组的最大和”为例,相当于我们在数组中,计算连续的子数组的和,找寻最大值。如在数组[3, -2, 1, 2, 4, -6, 5]中连续子数组的最大和为:3 + (-2) + 1 + 2 + 4 = 8


输入:[3, -2, 1, 2, 4, -6, 5]
输出:8


一定要准确的理解题意,如不是特别明确,建议与面试官再次沟通确认,避免需求与实现不一致的情况。


二、解决方案


连续子数组的最大和


这道面试题有几种解决方案呢?可能在很多个同学的脑海里会出现这样的一种方案:


1. 求连续子数组组合方案:


将数组中的元素进行连续子数组的组合,每一种组合计算出一个值,依次比较后取出最大值。那这种方式是可以肯定是可以最终的效果的,But这么处理的话,会有多少种组合方案呢?


以数组 [1, -1, 2, -3, 5]为例:
    连续子数组有:N + (N-1) + (N-2)...  +  1 = n*(n+1) / 2


随着数组长度N的值越大,组合数量肯定是越大!同时在获取阶乘后,还需要再次进行一次最大值得比较。


划重点:


此方案虽可以实现最终的效果,但是确实十分不可取的!


2. 最优解方案


在面试时面试题除了固定的套路和算法外,要多尝试逻辑思维的转变...


技术方案:
    1. 初始化两个变量:sum(连续子数组的累加和)、max(最大值)
    2. 遍历数组元素,考虑sum的情况: 
        sum >= 0,将当前元素的值进行累加
        sum < 0,注意,sum的值为负值,不管当前的元素值是什么,累加sum(负数)肯定值最终会变小的,所以此刻,要重新对sum进行赋值操作
    3. 每次遍历时,都要比较sum和max的大小, 如果 sum > max,进行赋值max = sum
    4. 返回最终的结果max


接下来,我们来看下代码的实现:


/**
 * getGreatestSumOfSubArray()
 * @description 获取连续子数组中最大和
 * @param Array arr 指定的数组
 * @returns Number sum 最大和
*/
function getGreatestSumOfSubArray (arr) {
  // 容错边界处理
  if (!Array.isArray(arr) || arr.length === 0) {
    return 0
  }
  // 解构,初始获取数组的第一个元素值
  // 注意:一定不能把sum和max设置初始化为0,必须要考虑数组元素中全部为负数的情况
  let [ sum ] = arr
  let [ max ] = arr
  let len = arr.length
  for (let i = 1; i < len; i++) {
    // 如果当前sum累加 < 0,重新初始化当前元素值;否则执行累加
    if (sum < 0) {
      sum = arr[i]
    } else {
      sum += arr[i]
    }
    // 比较累加和与最大值
    if (sum > max) {
      max = sum
    }
  }
  return max
}
// 调用
let max = getGreatestSumOfSubArray([3, -2, 1, 2, 4, -6, 5])
console.log(max) // 8


OK,这样我们就实现了需求,小朋友,你还有问号吗?


连续子数组的最小和


“连续子数组的最小和” 这个需求的实现原理和“连续子数组的最大和”的实现基本是一致的,唯一的区别点为:当sum的值 > 0为正数时,累加就无意义了,需要重新赋值为当前值。我们来看下代码的实现


/**
 * getLeastSumOfSubArray()
 * @description 获取连续子数组的最小和
 * @param Array arr 指定的数组
 * @returns Number min 最小和
*/
function getLeastSumOfSubArray (arr) {
  if (!Array.isArray(arr) || arr.length === 0) {
    return 0
  }
  // 初始化
  let [ sum ] = arr
  let [ min ] = arr
  // 遍历数组元素,如果sum是一个正数,累加就无意义,重新赋值为当前项;
  let len = arr.length
  for (let i = 1; i < len; i++) {
    if (sum > 0) {
      sum = arr[i]
    } else {
      sum += arr[i]
    }
    if (sum < min) {
      min = sum
    }
  }
  return min
}
let min = getLeastSumOfSubArray([-1, -2, 3, 2, -4, -8])
console.log(min) // -12 = (-4) + (-8)


相关文章
|
Android开发
Android Studio运行程序出现Session ‘app’: Error Launching activity 解决办法
原文:Android Studio运行程序出现Session ‘app’: Error Launching activity 解决办法 session "app":error launching activity 一下两种方法,可以轻松解决: 1. 2.把复选框去除:
4264 0
|
5天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
390 93
|
6天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
5天前
|
SQL 人工智能 自然语言处理
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
随着生成式AI的普及,Geo优化(Generative Engine Optimization)已成为企业获客的新战场。然而,缺乏标准化流程(Geo优化sop)导致优化效果参差不齐。本文将深入探讨Geo专家于磊老师提出的“人性化Geo”优化体系,并展示Geo优化sop标准化如何帮助企业实现获客效率提升46%的惊人效果,为企业在AI时代构建稳定的流量护城河。
394 156
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
|
5天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
282 158