前缀和:中心下标与数组乘积

文章目录

一、左右信息的统一视角

对于下标 i,可以把数组拆成三部分:

text 复制代码
[0, i) + nums[i] + (i, n)

中心下标比较左右两侧的和;除自身以外数组的乘积则把左右两侧的乘积相乘。两题的共同点是都不需要在处理每个 i 时重新扫描左右区间。

二、寻找数组的中心下标

LeetCode 724. 寻找数组的中心下标

dp[i] 表示下标 i 左侧所有元素的和,那么 dp[nums.length] 就是整个数组的总和。

如果 i 是中心下标,则有:

text 复制代码
左侧和 = 右侧和
dp[i] = dp[nums.length] - dp[i] - nums[i]

移项后可以直接判断:

text 复制代码
dp[i] * 2 + nums[i] == dp[nums.length]

这样只需要一个前缀和数组,不必再建立后缀和数组。代码从左向右检查,因此找到的第一个结果自然是最靠左的中心下标。

java 复制代码
class Solution {
    public int pivotIndex(int[] nums) {
        long[] dp = new long[nums.length + 1];
        for (int i = 1; i < nums.length + 1; i++) {
            dp[i] = dp[i - 1] + nums[i - 1];
        }

        for (int i = 0; i < nums.length; i++) {
            if (dp[i] * 2 + nums[i] == dp[nums.length]) {
                return i;
            }
        }
        return -1;
    }
}

时间复杂度为 O(n),空间复杂度为 O(n)。按照本题约束,int 足以保存总和;这里使用 long 可以降低代码对数值范围的依赖。

三、除了自身以外数组的乘积

LeetCode 238. 除了自身以外数组的乘积

如果先求全部元素的乘积,再除以 nums[i],遇到 0 时就无法处理,而且题目本身也要求不使用除法。可以分别保存左侧前缀积和右侧后缀积:

  • dpleft[i]:下标 0i - 1 的元素乘积;
  • dpright[i]:下标 ilen - 1 的元素乘积。

因此,下标 i 的答案为:

text 复制代码
ret[i] = dpleft[i] * dpright[i + 1]

数组两端没有元素的一侧按乘法单位元 1 处理,所以初始化 dpleft[0] = 1dpright[len] = 1

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int len = nums.length;
        int[] dpleft = new int[len + 1];
        int[] dpright = new int[len + 1];

        dpleft[0] = 1;
        dpright[len] = 1;
        for (int i = 0; i < len; i++) {
            dpleft[i + 1] = dpleft[i] * nums[i];
        }
        for (int i = len - 1; i >= 0; i--) {
            dpright[i] = dpright[i + 1] * nums[i];
        }

        int[] ret = new int[len];
        for (int i = 0; i < len; i++) {
            ret[i] = dpleft[i] * dpright[i + 1];
        }
        return ret;
    }
}

题目保证相关前缀积、后缀积与答案都在 32 位整数范围内,因此可以使用 int[]。时间复杂度为 O(n),额外空间复杂度为 O(n)

相关推荐
漂流瓶jz1 小时前
UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版
c++·算法·题解·aoapc·算法竞赛入门经典·uva
叠层归一研究院2 小时前
基于极限自指的叠层归一宇宙结构理论——无元外部封闭系统的内生区分模型
人工智能·经验分享·算法·agi
Selvaggia3 小时前
Diffusion Model 的基本原理与模型架构
算法
wabs6665 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
hanlin035 小时前
刷题笔记:力扣第41题-缺失的第一个正数
笔记·算法·leetcode
shehuiyuelaiyuehao5 小时前
算法50,分治归并,数组中的逆序对
java·算法
阳明山水6 小时前
校准分位数驱动智能库存决策
人工智能·深度学习·算法·机器学习·架构
雨落在了我的手上6 小时前
Java数据结构(十四):Map和Set
数据结构
码行山野赴时序归途6 小时前
链表家族收官篇:循环链表
c语言·开发语言·数据结构·链表
别动我齐刘海7 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人