跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

算法实战:前缀和与后缀和解决中心下标及数组乘积问题

针对寻找数组中心下标与除自身以外数组乘积两个经典问题,深入解析前缀和与前缀积的应用。通过预处理左右两侧累加或累乘结果,将时间复杂度优化至 O(N),避免暴力枚举带来的性能瓶颈。代码实现涵盖 C++ 解决方案,注重边界条件处理与空间换时间的策略,适合面试准备与算法能力提升。

萤火微光发布于 2026/3/28更新于 2026/10/2586 浏览
算法实战:前缀和与后缀和解决中心下标及数组乘积问题

寻找数组的中心下标

题目描述: 给定一个整数数组 nums,请找到一个索引位置,使得该位置左侧元素之和等于右侧元素之和。如果存在多个这样的位置,返回最小的那个;如果不存在,返回 -1。

示例: 输入:nums = [1, 7, 3, 6, 5, 6] 输出:3 解释:索引 3 左侧和为 1 + 7 + 3 = 11,右侧和为 5 + 6 = 11。

解法思路

要找到这个'平衡点',核心在于快速计算每个位置左右的和。如果每次遍历都重新求和,时间复杂度会达到 O(N^2)。利用前缀和的思想,我们可以预先计算出每个位置的左侧累积和与右侧累积和,从而将查询降为 O(1)。

具体做法是构建两个辅助数组:

  1. leftSum[i] 表示 i 左侧所有元素的和。
  2. rightSum[i] 表示 i 右侧所有元素的和。

遍历数组时,只要发现 leftSum[i] == rightSum[i],当前的 i 就是我们要找的中心下标。

C++ 代码实现

class Solution {
public:
    int pivotIndex(vector<int>& nums) {
        int n = nums.size();
        // f 存储左侧前缀和,g 存储右侧后缀和
        vector<int> f(n, 0), g(n, 0);
        
        // 计算左侧前缀和
        for (int i = 1; i < n; i++) {
            f[i] = f[i - 1] + nums[i - 1];
        }
        
        // 计算右侧后缀和
        for (int i = n - 2; i >= 0; i--) {
            g[i] = g[i + 1] + nums[i + 1];
        }
        
        // 查找平衡点
        for (int j = 0; j < n; j++) {
            if (f[j] == g[j]) return j;
        }
        
        return -1;
    }
};

除自身以外数组的乘积

题目描述: 给你一个整数数组 nums,请你返回一个数组 answer,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。注意:不能使用除法,且要求时间复杂度为 O(N)。

示例: 输入:nums = [1, 2, 3, 4] 输出:[24, 12, 8, 6] 解释:answer[0] = 2 * 3 * 4 = 24,以此类推。

解法思路

这道题的限制条件比较苛刻,不能用除法,意味着我们不能先算出总乘积再除以当前元素。我们需要分别计算每个位置左侧的乘积和右侧的乘积。

类似于前缀和的思路,我们可以维护两个数组:

  1. prefixProd[i] 表示 i 左侧所有元素的乘积(即 nums[0] * ... * nums[i-1])。
  2. suffixProd[i] 表示 i 右侧所有元素的乘积(即 nums[i+1] * ... * nums[n-1])。

最终结果 answer[i] 即为这两部分的乘积。这样既满足了 O(N) 的时间要求,也避免了除法操作。

C++ 代码实现

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size();
        vector<int> prefix(n, 1), suffix(n, 1), result(n);
        
        // 计算左侧前缀乘积
        for (int i = 1; i < n; i++) {
            prefix[i] = prefix[i - 1] * nums[i - 1];
        }
        
        // 计算右侧后缀乘积
        for (int i = n - 2; i >= 0; i--) {
            suffix[i] = suffix[i + 1] * nums[i + 1];
        }
        
        // 组合结果
        for (int i = 0; i < n; i++) {
            result[i] = prefix[i] * suffix[i];
        }
        
        return result;
    }
};

目录

  1. 寻找数组的中心下标
  2. 解法思路
  3. C++ 代码实现
  4. 除自身以外数组的乘积
  5. 解法思路
  6. C++ 代码实现

更多推荐文章

查看全部
  • 快速选择算法实战:第 K 大元素与最小 K 个数
  • 小厂架构师实战:AI Agent 辅助 Bug 定位与修复
  • 提示工程(Prompt Engineering):本质、技术与最佳实践
  • 英伟达与 GitHub 免费获取大模型 API Key 方法指南
  • Java 实体类为何不建议使用 is 前缀命名?以 is_deleted 为例
  • C++ 基础教程:从 Hello World 到变量类型
  • 高德地图离线部署方案:获取瓦片数据与私有化调用
  • Java Web 自研框架 18 年架构决策复盘与核心思路
  • 互联网产品经理转型大模型 AI 产品经理实战指南
  • GitHub Copilot Pro 学生免费认证与 VS Code 集成指南
  • 机器人动力学:牛顿欧拉法推导与详解
  • C++ 二叉搜索树 (BST) 详解:原理、核心操作与实战实现
  • Bing Webmaster 工具使用指南:站点验证与收录提交
  • 应届生无项目经验,求职碰壁该如何应对?
  • HTML5+CSS3+JavaScript 实现高木同学圣诞树 GalGame 开发
  • C++ STL 详解:从零实现 vector 容器
  • Sora2 API 调用实践及开源前端接入示例
  • Java OCR 工具 RapidOCR 集成指南:从环境配置到实战应用
  • C++ 核心面试题与底层原理详解
  • RabbitMQ 安装与运维指南:从部署到高级配置

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online