【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;
    }
}
相关推荐
侠客行03172 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪2 小时前
深入浅出LangChain4J
java·langchain·llm
灰子学技术4 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
老毛肚4 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
那个村的李富贵4 小时前
CANN加速下的AIGC“即时翻译”:AI语音克隆与实时变声实战
人工智能·算法·aigc·cann
风流倜傥唐伯虎4 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
二十雨辰4 小时前
[python]-AI大模型
开发语言·人工智能·python
power 雀儿5 小时前
Scaled Dot-Product Attention 分数计算 C++
算法
Yvonne爱编码5 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚5 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言