【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;
    }
}
相关推荐
YatHinLay37 分钟前
Spring Boot + Calcite 实现跨库查询
java
wabs66642 分钟前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
hanlin031 小时前
刷题笔记:力扣第41题-缺失的第一个正数
笔记·算法·leetcode
酷炫码神1 小时前
MosMos 创意效果与能力边界展示
java
Wang's Blog1 小时前
Java 接入Redis: 使用Jedis操作Redis
java·服务器·redis
事圆则缓1 小时前
Java 8 Lambda、Stream、Optional 与 Android 边界:从回调语法到运行时兼容
android·java
shehuiyuelaiyuehao1 小时前
算法50,分治归并,数组中的逆序对
java·算法
烽学长1 小时前
(附源码)基于Springboot+vue的图书阅读分享系统的设计与实现
java·spring boot·后端
Ivanqhz1 小时前
数据搬运是性能关键
java·服务器·网络·人工智能·深度学习
青山木2 小时前
RocketMQ 入门到原理(三):消息存储原理
java·后端·中间件·架构·rocketmq