华为OD机试真题---分割数组的最大差值

华为OD机试中的“分割数组的最大差值”是一道经典的数组处理问题,其核心在于找到一个分割点,将数组分割成两个非空子数组,使得两个子数组的和的差值最大。以下是对该题目的详细解析和实现方法:

一、题目描述

给定一个由若干整数组成的数组nums,可以在数组内的任意位置进行分割,将该数组分割成两个非空子数组(即左数组和右数组),分别对子数组求和得到两个值,计算这两个值的差值,并输出所有分割方案中差值最大的值。

二、输入与输出

  • 输入描述

    1. 第一行输入数组Q中元素个数n,1 < n < 100000。
    2. 第二行输入数字序列,以空格进行分隔,数字取值为4字节整数。
  • 输出描述

    • 输出差值的最大取值。

补充说明:
示例1
输入:

6
1 -2 3 4 -9 7

输出:

10
说明:
将数组 nums 划分为两个非空数组的可行方案有:
左数组 =[1]且 右数组=[-2,3,4,-9,7],和的差值=|1-3|=2;
左数组=[1,-2]且右数组=[3,4,-9,7],和的差值=|-1-5|=6;
左数组 =[1,-2,3]且 右数组 =[4,-9,7],和的差值 =|2-2|=0

三、解题思路

  1. 遍历数组

    • 我们从数组的第一个元素开始遍历,直到倒数第二个元素(因为我们需要将数组分成两部分,所以最后一个元素自然属于右部分,无需再遍历)。
  2. 计算当前位置之前的子数组和

    • 在遍历过程中,我们维护一个变量leftSum,用于记录当前位置之前的所有元素的和。
  3. 计算剩余部分的和

    • 对于每个遍历到的位置,我们可以计算出剩余部分的和rightSum,这可以通过整个数组的和sum减去leftSum得到。
  4. 计算差值并更新最大值

    • 对于每个分割点,我们计算两个子数组和的差值diff = abs(leftSum - rightSum),并将其与当前记录的最大差值maxDiff进行比较,如果diff更大,则更新maxDiff
  5. 优化

    • 注意到在计算差值时,我们可以避免重复计算rightSum,因为rightSum总是等于sum - leftSum。这样,我们只需要在每次遍历时更新leftSum,然后直接计算差值,从而提高了效率。

四、Java实现

这个问题可以用Java来解决。以下是一个Java实现的示例代码:

import java.util.Scanner;public class MaxDifference {/*** 主函数执行计算最大差值的操作* 该函数首先读取用户输入的一系列整数,然后计算这些整数的总和* 接着,它遍历这些整数,找到将这些整数分成两部分时,两部分和的最大差值*/public static void main(String[] args) {// 创建Scanner对象以读取用户输入Scanner scanner = new Scanner(System.in);// 读取用户输入的整数数量int n = scanner.nextInt();// 根据用户输入的数量创建一个整数数组int[] nums = new int[n];// 遍历数组,读取每个整数for (int i = 0; i < n; i++) {nums[i] = scanner.nextInt();}// 关闭Scanner对象,防止资源泄漏scanner.close();// 初始化总和变量,用于计算数组中所有整数的总和int sum = 0;// 遍历数组,计算总和for (int num : nums) {sum += num;}// 初始化最大差值变量,用于记录分割数组时两部分和的最大差值int maxDiff = 0;// 初始化左侧和变量,用于在遍历数组时累加左侧部分的和int leftSum = 0;// 遍历数组,直到倒数第二个元素,因为我们要比较的是两部分的和for (int i = 0; i < n - 1; i++) {// 累加左侧部分的和leftSum += nums[i];// 计算右侧部分的和int rightSum = sum - leftSum;// 计算当前分割位置的两部分和的差值int diff = Math.abs(leftSum - rightSum);// 更新最大差值maxDiff = Math.max(maxDiff, diff);}// 输出最大差值System.out.println(maxDiff);}
}

五、运行解析

假设用户输入如下:

6
1 -2 3 4 -9 7

代码解析步骤:
1.读取输入:

  • 用户输入 6,表示接下来会有 6 个整数。
  • 用户输入 1 -2 3 4 -9 7,这些整数将被存储在数组 nums 中。

2.初始化变量:

  • n = 6,表示数组长度为 6。
  • nums = [1, -2, 3, 4, -9, 7],存储用户输入的整数。
  • sum = 0,用于计算数组中所有整数的总和。
  • maxDiff = 0,用于记录分割数组时两部分和的最大差值。
  • leftSum = 0,用于在遍历数组时累加左侧部分的和。

3.计算总和:

  • 遍历数组 nums,计算总和 sum:

for (int num : nums) {
sum += num;
}

  • 计算结果:sum = 1 + (-2) + 3 + 4 + (-9) + 7 = 4
    4.计算最大差值:
  • 遍历数组 nums,直到倒数第二个元素(即 i < n - 1),计算每种分割方式下的两部分和的差值,并更新 maxDiff:
for (int i = 0; i < n - 1; i++) {leftSum += nums[i];int rightSum = sum - leftSum;int diff = Math.abs(leftSum - rightSum);maxDiff = Math.max(maxDiff, diff);}
  • 详细计算过程如下:
    • 当 i = 0 时:
      • leftSum = 1
      • rightSum = sum - leftSum = 4 - 1 = 3
      • diff = |1 - 3| = 2
      • maxDiff = Math.max(0, 2) = 2
    • 当 i = 1 时:
      • leftSum = 1 + (-2) = -1
      • rightSum = sum - leftSum = 4 - (-1) = 5
      • diff = |-1 - 5| = 6
      • maxDiff = Math.max(2, 6) = 6
    • 当 i = 2 时:
      • leftSum = -1 + 3 = 2
      • rightSum = sum - leftSum = 4 - 2 = 2
      • diff = |2 - 2| = 0
      • maxDiff = Math.max(6, 0) = 6
    • 当 i = 3 时:
      • leftSum = 2 + 4 = 6
      • rightSum = sum - leftSum = 4 - 6 = -2
      • diff = |6 - (-2)| = 8
      • maxDiff = Math.max(6, 8) = 8
    • 当 i = 4 时:
      • leftSum = 6 + (-9) = -3
      • rightSum = sum - leftSum = 4 - (-3) = 7
      • diff = |-3 - 7| = 10
      • maxDiff = Math.max(8, 10) = 10
        5.输出结果:
  • 最终,maxDiff 的值为 10,程序输出:
  System.out.println(maxDiff);
  • 输出结果:10
    总结
  • 通过上述步骤,程序计算了将数组 [1, -2, 3, 4, -9, 7] 分成两部分时,两部分和的最大差值,并输出了结果 10。
六、注意事项
  1. 时间复杂度

    • 上述实现的时间复杂度为O(n),其中n为数组的长度。这是因为我们只需要遍历一次数组即可找到最大差值。
  2. 空间复杂度

    • 上述实现的空间复杂度为O(1),仅使用了常数空间来存储几个变量。我们没有使用额外的数据结构来存储数据,因此空间复杂度很低。
  3. 输入验证

    • 在实际应用中,可能需要添加对输入的验证,以确保输入符合题目要求。例如,可以检查输入的数字是否在指定范围内,以及数组是否为空等。这可以通过添加适当的条件语句来实现。
  4. 代码优化

    • 在计算差值时,我们可以直接写成Math.abs(2 * leftSum - sum),而不是先计算rightSum再计算差值。这样做可以减少不必要的计算,提高代码的效率。
  5. 代码可读性

    • 在编写代码时,我们应该注意代码的可读性。例如,可以使用有意义的变量名、添加适当的注释以及使用空格和缩进来使代码更加清晰易读。
  6. 异常处理

    • 在实际应用中,我们还需要考虑异常处理。例如,如果输入的数据格式不正确或者输入的数据超出了预期的范围,我们应该能够捕获这些异常并给出适当的错误提示。这可以通过使用try-catch语句来实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453736.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

处理文件上传和进度条的显示(进度条随文件上传进度值变化)

成品效果图&#xff1a; 解决问题&#xff1a;上传文件过大时&#xff0c;等待时间过长&#xff0c;但是进度条却不会动&#xff0c;只会在上传完成之后才会显示上传完成 上传文件的upload.component.html <nz-modal [(nzVisible)]"isVisible" [nzTitle]"文…

python包以及异常、模块、包的综合案例(较难)

1.自定义包 python中模块是一个文件&#xff0c;而包就是一个文件夹 有这个_init_.py就是python包&#xff0c;没有就是简单的文件夹 包的作用&#xff1a;当我们的模块越来越多时&#xff0c;包可以帮助我们管理这些模块&#xff0c;包的作用就是包含多个模块&#xff0c;但包…

【命令操作】信创终端系统上timedatectl命令详解 _ 统信 _ 麒麟 _ 方德

原文链接&#xff1a;【命令操作】信创终端系统上timedatectl命令详解 | 统信 | 麒麟 | 方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于如何在信创终端系统上使用timedatectl命令的详细介绍。timedatectl 是Linux系统中非常实用的时间管理工具&#xff0c;…

学习写作--polyGCL.md

POLYGCL: GRAPH CONTRASTIVE LEARNING VIA LEARNABLE SPECTRAL POLYNOMIAL filters 这篇工作的摘要和引言写的特别好&#xff08;不愧是ICLR spotlight&#xff09; 摘要 第一步&#xff0c;设定背景 Recently, Graph Contrastive Learning (GCL) has achieved significantl…

使用Flask实现本机的模型部署

前言 模型部署是指将大模型运行在专属的计算资源上&#xff0c;使模型在独立的运行环境中高效、可靠地运行&#xff0c;并为业务应用提供推理服务。其目标是将机器学习模型应用于实际业务中&#xff0c;使最终用户或系统能够利用模型的输出&#xff0c;从而发挥其作用。 一、设…

12 django管理系统 - 注册与登录 - 登录

为了演示方便&#xff0c;我就直接使用models里的Admin来演示&#xff0c;不再创建用户模型了。 ok&#xff0c;先做基础配置 首先是在base.html中&#xff0c;新增登录和注册的入口 <ul class"nav navbar-nav navbar-right"><li><a href"/ac…

黑马软件测试第一篇_Linux

Linux 操作系统 说明: 所有硬件设备组装完成后的第⼀一层软件, 能够使⽤用户使⽤用硬件设备的软件 即为操作系统 常见分类 桌⾯面操作系统: Windows/macOS/Linux移动端操作系统: Android(安卓)/iOS(苹果)服务器器操作系统: Linux/Windows Server嵌⼊入式操作系统: Android(底…

linux线程 | 同步与互斥 | 线程池以及知识点补充

前言&#xff1a;本节内容是linux的线程的相关知识。本篇首先会实现一个简易的线程池&#xff0c; 然后再将线程池利用单例的懒汉模式改编一下。 然后再谈一些小的知识点&#xff0c;比如自旋锁&#xff0c; 读者写者问题等等。 那么&#xff0c; 现在开始我们的学习吧。 ps:本…

吴恩达深度学习笔记(6)

正交化 为了提高算法准确率&#xff0c;我们想到的方法 收集更多的训练数据增强样本多样性使用梯度下降将算法使算法训练时间更长换一种优化算法更复杂或者更简单的神经网络利用dropout 或者L2正则化改变网络框架更换激活函数改变隐藏单元个数 为了使有监督机制的学习系统良…

ansible playbooks

文章目录 一&#xff0c;ansible剧本二&#xff0c;ansible playbooks主要特性三&#xff0c;yaml基本语法规则四&#xff0c;剧本playbooks的组成结构五&#xff0c;yaml编写1.示例2.运行playbook2.1 运行2.2 检查yaml文件的语法是否正确2.3 检查tasks任务2.3 检查生效的主机2…

maven创建父子项目

创建父类 创建子模块 添加文件夹 配置tomcat 参考 然后启动项目即可 参考 https://blog.csdn.net/gjtao1130/article/details/115000022

Linux——shell 编程基础

基本介绍 shell 变量 环境变量&#xff08;也叫全局变量&#xff09; 位置参数变量 预定义变量 运算符 条件判断 流程控制 if 单分支&多分支 case 语句 for循环 while 循环 read 读取控制台输入 函数 系统函数 basename 获取文件名 dirname 获取目录路径 自定义函数 综…

DataWhale10月动手实践——Bot应用开发task03学习笔记

一、工作流 1. 工作流的定义 工作流由多个节点组成&#xff0c;这些节点可以包括大语言模型&#xff08;LLM&#xff09;、代码模块、逻辑判断工具、插件等。每个节点需要不同的信息来执行其功能。工作流的核心含义是&#xff1a;对工作流程及其操作步骤之间的业务规则进行抽…

中国信通院联合中国电促会开展电力行业企业开源典型实践案例征集

自2021年被首次写入国家“十四五”规划以来&#xff0c;开源技术发展凭借其平等、开放、协作、共享的优秀创作模式&#xff0c;正持续成为推动数字技术创新、优化软件生产模式、赋能传统行业转型升级、助力企业降本增效的重要引擎。电力是国民经济的重要基础性产业&#xff0c;…

开源神器!CodeFormer:一键去除马赛克,高清修复照片视频

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; 微信公众号&#xff5c;搜一搜&…

Docker安装Mysql数据库

不同的应用程序可能依赖于不同版本的 MySQL 或具有不同的配置需求。通过 Docker&#xff0c;每个 MySQL 实例都可以运行在独立的容器中&#xff0c;与宿主机以及其他容器的环境相互隔离。这有效避免了因不同应用对 MySQL 版本、依赖库等方面的差异而导致的冲突。例如&#xff0…

盛元广通数字化实验动物中心LIMS综合管理系统

盛元广通数字化实验动物中心LIMS综合管理系统通过集成各种功能&#xff0c;从实验申请、伦理审批、笼位预约、动物采购到开展动物实验、数据归档等全流程智能化管理&#xff0c;保证了实验信息随时可查&#xff0c;管理可视化、流程简单化。实验动物中心采用电脑端、APP和微信小…

LangSplat和3D language fields简略介绍

LangSplat: 3D Language Gaussian Splatting 相关技术拆分解释&#xff1a; 3dgs&#xff1a;伟大无需多言SAM&#xff1a;The Segment Anything Model&#xff0c;是图像分割领域的foundational model&#xff0c;已经用在很多视觉任务上&#xff08;如图像修复、物体追踪、图…

Linux目录

一、虚拟机环境配置 1.安装虚拟机 安装步骤 新建虚拟机-->典型安装-->选择稍后安装操作系统-->选择系统类型和版本&#xff08;这里安装的是CentOS7 64位&#xff09;-->选择虚拟机文件路径&#xff08;建议每台虚拟机单独存放并且路径不要有中文&#xff09;--&…

商淘云连锁管理系统

商淘云连锁管理系统助力连锁企业实现“人货账”全方位数字化管理&#xff0c;它依托连锁品牌进销存管理实现门店订货、线下收银、线上商城、会员营销等一体化管理。 门店订货补货支持连锁直营、加盟 不同门店不同进货价、不同门店不同商品、不同门店在线或者账期支付、门店PC或…