[路飞]_1658-将 x 减到 0 的最小操作数

简介: 1658-将 x 减到 0 的最小操作数

网络异常,图片无法展示
|


「这是我参与2022首次更文挑战的第34天,活动详情查看:2022首次更文挑战


[题目地址]


给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。


如果可以将 x恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1


示例 1:


输入: nums = [1,1,4,2,3], x = 5
输出: 2
解释: 最佳解决方案是移除后两个元素,将 x 减到 0 。
复制代码


示例 2:


输入: nums = [5,6,7,8,9], x = 4
输出: -1
复制代码


示例 3:


输入: nums = [3,2,20,1,1,3], x = 10
输出: 5
解释: 最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。
复制代码


提示:


  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 104
  • 1 <= x <= 109


递归求解,超时


解题思路


本题题意并不复杂,要求我们每次可以在整数数组的边缘删除一个元素,并在目标值上减去响应的数字,如果刚好可以把目标值减为 0,返回最小的操作次数。


这样的一个问题,我们首先可以想到的解题思路可能是使用递归:


  1. 递归函数传入剩余数值和当前区间,初始传入 target = x,l = 0,r = nums.length-1
  2. 每次减去左边的元素或者右边的元素,并修改对应的 target,l,r
  3. 递归函数的第一个退出条件是 target===0,此时说明找到一种操作可以将目标值减为 0,如果此时的操作次数小于已记录的做小操作次数,更新最小操作次数。
  4. 递归函数的另一种退出条件是 l>r || target<0 || 此时的操作次数大于等于已记录的最小操作次数,这个时候说明继续操作是没有意义的,退出递归。


代码实现


var minOperations = function (nums, x) {
  /**
   * 递归函数
   * @param {number[]} target 剩余要减去的数值
   * @param {number} l 未操作区间的起始下标
   * @param {number} r 未操作区间的结束下标
   * @return  void
   */
  function calc(target, l, r) {
    if (target === 0 && l - 0 + len - r - 1 < res) {
      res = l - 0 + len - r - 1
      return
    }
    if (l > r || target < 0 || l - 0 + len - r - 1 >= res) {
      return
    }
    calc(target - nums[l], l + 1, r)
    calc(target - nums[r], l, r - 1)
  }
  // 获取输入数组长度
  const len = nums.length
  // 初始化结果值为数组长度+1,即一个非法值
  let res = len + 1
  // 调用递归函数
  calc(x, 0, len - 1)
  // 如果结果值合法,返回结果值,否则返回 -1
  return res > len ? -1 : res
}
复制代码


但是以上算法的时间复杂度为 O(n²),没有达到本题的要求,提交会超时。


反向思维,滑动窗口


解题思路


递归解题超时了,此时我们换一种思路,既然本题要求每次只能在数组的边缘删除元素,那么剩余的元素必然是在数组的 “中间的”,也就是说它们必然是连续的,那么我们只要找到一个连续子数组,其中元素的和值等于输入数组的元素和值减去目标值即可。


代码实现


var minOperations = function (nums, x) {
  // 获取输入数组的长度
  const len = nums.length
  // 获取输入数组中整数的和值
  let total = 0
  for (let i = 0; i < len; i++) total += nums[i]
  // 如果目标值大于和值,说明不可能减到 0,返回 -1
  if (total < x) return -1
  // 如果目标值等于和值,说明需要把数组中所有元素都减去,返回数组长度
  if (total === x) return len
  // 初始化结果值为数组长度+1,即一个非法值
  let res = len + 1,
    // 区间起始下标为0
    l = 0,
    // 区间结束下标为0
    r = 0
  // 区间整数和值为0
  sum = 0
  // 计算数组中整数和值与目标值的差值 => 目标区间中元素的和值
  const diff = total - x
  // 当区间结束下标没有走到数组末尾
  while (r < len) {
    // 累加和值
    sum += nums[r]
    // 如果区间中和值大于差值,则应该把区间最左侧的整数进行删除
    while (sum > diff) {
      sum -= nums[l]
      l++
    }
    // 如果区间和值等于差值,说明找到了一种操作方式,尝试更新最小操作次数
    if (sum === diff) res = Math.min(res, len - r + l - 1)
    r++
  }
  // 如果结果值合法,返回结果值,否则返回 -1
  return res > len ? -1 : res
}
复制代码


以上算法的时间复杂度为 O(n),提交后击败 90+% 的用户。


至此我们就完成了 1658-将 x 减到 0 的最小操作数


如有任何问题或建议,欢迎留言讨论!👏🏻👏🏻👏🏻

相关文章
|
Dubbo Java 应用服务中间件
微服务框架(十)Maven Archetype制作Dubbo项目原型
  此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。   本文为Maven Archetype的制作及使用,使用archetype插件制作Dubbo项目原型
|
4月前
|
人工智能 物联网
Face-to-Photo 模型开源!联名麦橘MERJIC,遇见另一个你!
魔搭 DiffSynth-Studio 团队携手知名创作者麦橘MERJIC,正式开源全新 AI 图像生成模型——Face-to-Photo!该模型基于 Qwen-Image-Edit,采用 LoRA 的模型结构,专为人脸图像生成而优化,将一张普通的人脸照片转化…
761 13
|
存储 数据采集 监控
【2022持续更新】大数据最全知识点整理-数据仓库篇
【2022持续更新】大数据最全知识点整理-数据仓库篇
2632 0
【2022持续更新】大数据最全知识点整理-数据仓库篇
|
11月前
|
机器学习/深度学习 人工智能 数据处理
OpenBioMed:开源生物医学AI革命!20+工具链破解药物研发「死亡谷」
OpenBioMed 是清华大学智能产业研究院(AIR)和水木分子共同推出的开源平台,专注于 AI 驱动的生物医学研究,提供多模态数据处理、丰富的预训练模型和多样化的计算工具,助力药物研发、精准医疗和多模态理解。
559 1
OpenBioMed:开源生物医学AI革命!20+工具链破解药物研发「死亡谷」
|
11月前
|
存储 关系型数据库 BI
巧用 Navicat URI,一键实现团队 BI 工作区分享
今天,我们将手把手教大家如何通过Navicat软件实现阿里云 PolarDB 团队快速分享的操作。
|
机器学习/深度学习 人工智能 算法
《AI芯片:如何让硬件与AI计算需求完美契合》
在人工智能快速发展的今天,AI芯片成为推动该领域前行的关键力量。AI芯片如同“超级大脑”,支撑着从智能语音助手到自动驾驶汽车等各种复杂应用。它通过GPU、ASIC和FPGA等架构,优化矩阵运算、内存管理和数据传输,满足大规模数据处理需求。尽管面临通用性和成本挑战,未来AI芯片有望在异构计算、新兴技术和降低成本方面取得突破,为AI发展注入强大动力。
737 17
|
Web App开发 数据采集 开发者
如何解决ChromeDriver 126找不到chromedriver.exe问题
当使用Selenium与ChromeDriver 126时,遇到`chromedriver.exe`找不到的错误,可能是因为版本不匹配、文件路径错误或系统设置不当。解决方法包括:匹配Chrome浏览器版本下载ChromeDriver,确保文件在正确路径且有执行权限,以及调整系统设置允许执行。示例代码展示了如何设置代理IP、user-agent和cookie来运行Selenium爬虫。通过这些步骤,可以确保爬虫程序顺利运行。
1281 2
如何解决ChromeDriver 126找不到chromedriver.exe问题
ThreeJs控制模型的隐藏与显示
这篇文章讲解了如何在Three.js中通过代码控制3D模型的显示与隐藏状态。
298 3
ThreeJs控制模型的隐藏与显示
|
人工智能 安全 图形学
【AI落地应用实战】篡改检测技术前沿探索——从基于检测分割到大模型
在数字化洪流席卷全球的当下,视觉内容已成为信息交流与传播的核心媒介,然而,随着PS技术和AIGC技术的飞速发展,图像篡改给视觉内容安全带来了前所未有的挑战。 本文将探讨篡改检测技术的现实挑战,分享篡改检测技术前沿和最新应用成果。
|
人工智能 弹性计算 机器人
如何在阿里云一键部署FlowiseAI
FlowiseAI 是一款开源低代码开发工具,专为构建定制化的语言学习模型(LLM)应用设计。用户可通过拖放界面轻松创建和管理AI驱动的应用,如聊天机器人和数据分析工具。它基于LangChain框架,支持多种AI模型和数据库集成,实现高度定制化的流程自动化。在阿里云上,可以通过一键部署链接快速部署FlowiseAI,并通过简单的几步配置开始使用。详细操作步骤包括创建ECS实例、获取登录信息等。更多细节可见FlowiseAI官网。