【LeetCode精选算法】前缀和专题一

目录

系列文章目录

[1. 一维前缀和(easy)](#1. 一维前缀和(easy))

[2. 二维前缀和(medium)](#2. 二维前缀和(medium))

[27. 寻找数组的中心下标(easy)](#27. 寻找数组的中心下标(easy))

[28. 除自身以外数组的乘积(medium)](#28. 除自身以外数组的乘积(medium))


1. 一维前缀和(easy)

题目链接

解题思路

使用前缀和数组 dp,其中 dp[i] 表示从第 1 个元素到第 i 个元素的和。预处理后,区间 [l, r] 的和可以通过 dp[r] - dp[l-1] 快速求得。

Java 代码

java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int q = scan.nextInt();
        int[] arr = new int[n + 1];
        long[] dp = new long[n + 1];

        for (int i = 1; i <= n; i++) {
            arr[i] = scan.nextInt();
        }
        for (int i = 1; i <= n; i++) {
            dp[i] = dp[i - 1] + arr[i];
        }
        while (q-- > 0) {
            int l = scan.nextInt();
            int r = scan.nextInt();
            System.out.println(dp[r] - dp[l - 1]);
        }
    }
}

2. 二维前缀和(medium)

题目链接

解题思路

定义 dp[i][j] 为从 (1,1)(i,j) 的矩形区域和。递推公式为:
dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + arr[i][j]

查询子矩阵 (x1,y1)(x2,y2) 的和为:
dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]

Java 代码

java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), m = in.nextInt(), q = in.nextInt();
        int[][] arr = new int[n + 1][m + 1];
        long[][] dp = new long[n + 1][m + 1];

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                arr[i][j] = in.nextInt();
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + arr[i][j];
            }
        }
        while (q-- > 0) {
            int x1 = in.nextInt(), y1 = in.nextInt();
            int x2 = in.nextInt(), y2 = in.nextInt();
            System.out.println(dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1]);
        }
    }
}
复制代码

27. 寻找数组的中心下标(easy)

题目链接

解题思路

分别计算前缀和数组 lsum 和后缀和数组 rsum,遍历每个位置 i,若 lsum[i] == rsum[i] 则返回 i

Java 代码

java 复制代码
class Solution {
    public int pivotIndex(int[] nums) {
        int n = nums.length;
        int[] lsum = new int[n];
        int[] rsum = new int[n];
        for (int i = 1; i < n; i++) {
            lsum[i] = lsum[i - 1] + nums[i - 1];
        }
        for (int i = n - 2; i >= 0; i--) {
            rsum[i] = rsum[i + 1] + nums[i + 1];
        }
        for (int i = 0; i < n; i++) {
            if (lsum[i] == rsum[i]) return i;
        }
        return -1;
    }
}

28. 除自身以外数组的乘积(medium)

题目链接

解题思路

分别计算前缀积数组 lprod 和后缀积数组 rprod,则 ret[i] = lprod[i] * rprod[i]

Java 代码

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] lprod = new int[n];
        int[] rprod = new int[n];
        lprod[0] = 1;
        rprod[n - 1] = 1;
        for (int i = 1; i < n; i++) {
            lprod[i] = lprod[i - 1] * nums[i - 1];
        }
        for (int i = n - 2; i >= 0; i--) {
            rprod[i] = rprod[i + 1] * nums[i + 1];
        }
        int[] ret = new int[n];
        for (int i = 0; i < n; i++) {
            ret[i] = lprod[i] * rprod[i];
        }
        return ret;
    }
}
相关推荐
fqbqrr2 小时前
2606C++,C++构的多态
开发语言·c++
biter down3 小时前
从 0 到 1 搭建 Python 接口自动化测试框架(博客系统实战)
开发语言·python
小欣加油3 小时前
leetcode56 合并区间
c++·算法·leetcode·职场和发展
lqqjuly3 小时前
前沿算法深度解析(二)
人工智能·算法·机器学习
wang09073 小时前
自己动手写一个spring之IOC_2
java·后端·spring
来杯@Java3 小时前
学生选课管理系统(基于springboot+vue前后端分离的项目)计算机毕业设计java
java·spring boot·spring·vue·毕业设计·maven·mybatis
徐小夕4 小时前
万字长文!千万级文档 RAG 知识库系统落地实践
前端·算法·github
threelab4 小时前
Three.js 物理模拟着色器 | 三维可视化 / AI 提示词
开发语言·前端·javascript·人工智能·3d·着色器
武器大师724 小时前
lv_binding_js 代码解读
开发语言·javascript·ecmascript