当前位置: 首页 > news >正文

LeetCode 724:寻找数组的中心下标 | 前缀和的平衡点

LeetCode 724:寻找数组的中心下标 | 前缀和的平衡点

引言

寻找数组的中心下标(Find Pivot Index)是 LeetCode 第 724 题,难度为 Easy。题目要求在数组中找到某个索引,使得该索引左侧所有元素的和等于右侧所有元素的和。如果存在这样的索引,返回它;如果不存在,返回 -1。

这道题虽然是简单难度,但蕴含了前缀和思想的精髓。通过预先计算前缀和,我们可以在 O(n) 时间内找到中心下标。本文将详细分析这个问题及其扩展应用。

问题分析

题目描述

给定一个整数数组 nums,计算并返回数组的"中心索引"。如果存在中心索引 i,则满足 nums[0] + nums[1] + ... + nums[i-1] == nums[i+1] + nums[i+2] + ... + nums[n-1]。如果中心索引位于数组的最左端,则左侧总和为 0,同样的定义也适用于数组的最右端。如果不存在中心索引,返回 -1。

例如,输入 nums = [1, 7, 3, 6, 5, 6],输出为 3,因为索引 3 左侧的元素和为 1+7+3=11,右侧的元素和为 5+6=11。输入 nums = [1, 2, 3],输出为 -1,因为不存在满足条件的中心索引。

问题特点

这道题的关键挑战是如何高效地计算每个索引左侧和右侧的元素和。如果对每个索引都重新计算左右和,时间复杂度为 O(n²)。通过使用前缀和,我们可以将每个索引的左右和计算优化到 O(1),总时间复杂度为 O(n)。

解决方案

前缀和优化

def pivotIndex(nums): total_sum = sum(nums) left_sum = 0 for i in range(len(nums)): if left_sum == total_sum - left_sum - nums[i]: return i left_sum += nums[i] return -1

这个方法首先计算数组的总和。然后遍历数组,维护一个变量 left_sum 表示当前索引左侧的元素和。对于索引 i,右侧的元素和等于 total_sum - left_sum - nums[i]。如果 left_sum 等于这个值,说明 i 是中心索引。

详细解析

初始化 total_sum = sum(nums),计算整个数组的元素和。初始化 left_sum = 0,表示索引 0 左侧没有元素。

遍历到索引 i 时,首先检查 left_sum == total_sum - left_sum - nums[i] 是否成立。如果成立,说明索引 i 的左右和相等,返回 i。然后更新 left_sum += nums[i],为下一次检查做准备。

如果遍历结束都没有找到中心索引,返回 -1。

算法正确性证明

中心索引的定义

对于索引 i,如果它是中心索引,则满足:
sum(nums[0:i]) = sum(nums[i+1:n])

其中 sum(nums[0:i]) 表示 nums[0] 到 nums[i-1] 的和,sum(nums[i+1:n]) 表示 nums[i+1] 到 nums[n-1] 的和。

正确性分析

在遍历到索引 i 时,left_sum 正好等于 sum(nums[0:i]),因为 left_sum 在遍历过程中逐步累加每个元素。total_sum - left_sum - nums[i] 正好等于 sum(nums[i+1:n]),因为 total_sum 是所有元素之和,减去 left_sum(左侧之和)和 nums[i](当前元素)后,就是右侧之和。

因此,条件 left_sum == total_sum - left_sum - nums[i] 与中心索引的定义等价。

复杂度分析

时间复杂度

时间复杂度为 O(n),因为我们首先用一次遍历计算总和,然后第二次遍历查找中心索引。虽然有两个遍历,但总体仍然是线性的。

空间复杂度

空间复杂度为 O(1),只使用了常数个额外变量。

代码实现

Python 实现

def pivotIndex(nums): total_sum = sum(nums) left_sum = 0 for i in range(len(nums)): if left_sum == total_sum - left_sum - nums[i]: return i left_sum += nums[i] return -1

Java 实现

public int pivotIndex(int[] nums) { int totalSum = 0; for (int num : nums) { totalSum += num; } int leftSum = 0; for (int i = 0; i < nums.length; i++) { if (leftSum == totalSum - leftSum - nums[i]) { return i; } leftSum += nums[i]; } return -1; }

边界情况处理

空数组

当数组为空时,不存在中心索引,应该返回 -1。代码中,total_sum = 0,循环不会执行,返回 -1。

单个元素

当数组只有一个元素时,该元素是中心索引,因为左侧和右侧都是 0。例如 nums = [10],输出应为 0。代码中,total_sum = 10,left_sum = 0,检查 i = 0 时,条件为 0 == 10 - 0 - 10 = 0,成立,返回 0。

全相同元素

例如 nums = [1, 1, 1, 1],中心索引可能是 1 或 2。代码会返回第一个满足条件的索引。

无中心索引

例如 nums = [1, 2, 3],没有任何索引满足左右和相等,代码返回 -1。

全零数组

例如 nums = [0, 0, 0, 0],任何索引都可能满足条件。代码会返回第一个满足条件的索引,即 0。

测试用例

def test_pivot_index(): assert pivotIndex([1, 7, 3, 6, 5, 6]) == 3 assert pivotIndex([1, 2, 3]) == -1 assert pivotIndex([2, 1, -1]) == 0 assert pivotIndex([1, -1, 2, -2]) == 2 assert pivotIndex([0, 0]) == 0 assert pivotIndex([0, 0, 0, 0]) == 0 assert pivotIndex([]) == -1 assert pivotIndex([10]) == 0 print("所有测试用例通过!")

扩展问题

返回所有中心索引

如果题目要求返回所有中心索引,而不是第一个,可以收集所有满足条件的索引后返回列表:

def allPivotIndices(nums): total_sum = sum(nums) left_sum = 0 result = [] for i in range(len(nums)): if left_sum == total_sum - left_sum - nums[i]: result.append(i) left_sum += nums[i] return result

中心下标的变体

在某些变体中,可能要求左右和的绝对值相等,或者要求左右和的乘积相等。核心思路类似,都是利用前缀和来快速计算左右和。

实际应用场景

寻找中心下标的问题在现实中有很多应用。在物理学中,可以用来寻找杜杆的支点,使得左右两边的力矩相等。在经济学中,可以用来寻找平衡点,使得左边和右边的贡献相等。在数据分析和统计分析中,可以用来寻找数据的"中心",类似于中位数但考虑的是元素值而非位置。

从算法角度看,这个问题展示了前缀和在解决"平衡问题"中的应用。通过预先计算总和并在遍历中动态维护左侧和,我们可以在 O(n) 时间内找到平衡点。

总结

寻找数组的中心下标虽然是一道简单难度的题目,但蕴含了前缀和思想的精髓。通过使用前缀和,我们可以在 O(n) 时间和 O(1) 空间内解决这个问题。

这个问题的关键洞察是:利用总和和左侧和的关系,可以在 O(1) 时间内计算右侧和。这种"预计算+遍历"的思想是解决很多前缀和相关问题的基础。希望通过本文的讲解,读者能够深入理解前缀和的应用,并将其推广到更多类似问题的解决中。

http://www.jsqmd.com/news/875061/

相关文章:

  • [智能体-42]:深度解读:Python 免编译 + 动态执行,支撑智能体落地大模型决策
  • Juno平台TF-A安全调试功能恢复与配置指南
  • 深入解析:浏览器如何“咀嚼”HTML头部——从字节流到渲染树的完整链路与性能优化实战
  • 鸿蒙electron跨端框架PC墨案写作实战:把 Markdown 正文区做成桌面写作的中心
  • LeetCode 1248:统计「优美子数组」 | 前缀和与奇数计数
  • 基于FeFET的动态可重构FPGA:实现亚纳秒级上下文切换的硬件加速新架构
  • 司法AI风险评估:性能与公平性的技术悖论与工程实践
  • 反事实推理:用因果视角评估与缓解AI模型偏见
  • 基于LLM与多智能体的微服务自治运维系统设计与实践
  • 边缘计算融合触觉互联网与数字孪生:构建超低延迟人机交互框架
  • 稀疏结式与动作矩阵:多项式方程组求解的几何代数化方法
  • 鸿蒙electron跨端框架PC片段匣实战:给常用代码片段一个能搜索、复制和整理的桌面仓
  • FPGA加速机器学习在粒子物理触发系统中的应用与实战
  • 计算机视觉模型失败模式自动化发现与自然语言描述技术详解
  • Unity PBR材质工作流:800个开箱即用的工业级材质球
  • SMGI框架:通用人工智能的结构元模型与实现路径解析
  • 前缀和与差分 | 数组区间查询的利器
  • TabularMark表格数据水印:原理、实现与参数调优实战
  • LeetCode 560:和为 K 的子数组 | 前缀和与哈希表
  • 除了Easy App Locker,还有哪些Mac应用加锁方案?横向对比与避坑指南
  • Claude写代码到底靠不靠谱?实测37个真实开发任务后,我删掉了80%的Copilot订阅
  • 边缘计算中LLM部署的挑战与CLONE系统优化方案
  • 2026年比较好的新疆低压电力电缆/新疆高压电力电缆定制加工厂家推荐 - 品牌宣传支持者
  • AI+PDCA循环:构建医院后勤韧性系统的实践与思考
  • Cortex-R82集成ELA-600调试模块的信号连接问题解析
  • 2026年4月商用中央空调直销厂家口碑推荐,口碑好的商用中央空调哪家好,空气循环,保持室内空气新鲜 - 品牌推荐师
  • 别再被GPG签名卡住了!手把手教你修复Kali老版本apt更新源报错
  • 最后一公里交付失控?AI Agent+IoT+数字孪生闭环正在重构LSP技术栈——3家上市物流科技公司CTO联合预警
  • 安卓加固反调试核心机制:D-Bus监听与/proc/self/maps检测绕过实战
  • Debian挂载NFS远程硬盘踩坑实录:权限拒绝、连接超时问题一站式解决