基础算法之前缀和--Java实现(上)--LeetCode题解:【模板】前缀和-【模板】二维前缀和-寻找数组的中心下标-除自身以外数组的乘积

这里是Themberfue

【模板】前缀和

题目解析

本题就是求给定两个索引的之间的数组和,比如:给定1和3下标索引,那么就求出,下标1到下标3所有元素的和即可。

算法讲解

· 利用前缀和可以快速求出数组中某一连续区间的和。

· 所以我们需要先预处理出来一个前缀和数组 dp[],dp[i] 表示 [1, i]这个区间数组的和。

· 根据推导,我们可以得出状态转移方程,也就是当前位置的前缀和等于上一个位置的前缀和加上当前位置数组的元素。即 dp[i] = dp[i - 1] + arr[i]。

· 为了防止 dp 数组下标越界访问,我们一般以 1 为起点计数。所以记得给 dp 数组的下标0位置初始为0。

· 但现在我们要求给定区间的和,有了 dp 数组就好求了,比如要求求出 [2, 5]的下标和,那么其实就是 dp[5] - dp[1]。

· 总结公式:[left, right] => dp[right] - dp[left - 1]

编写代码

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

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), q = sc.nextInt();

        // 创建前缀和数组
        long[] dp = new long[n + 1];
        for (int i = 1; i <= n; i++) {
            dp[i] = dp[i - 1] + sc.nextInt();
        }

        // 使用前缀和数组
        for (int i = 0; i < q; i++) {
            int left = sc.nextInt(), right = sc.nextInt();
            System.out.println(dp[right] - dp[left - 1]);
        }
    }
}

【模板】二维前缀和

题目解析

此题与上题类似,不过就是从一维数组变成了二维数组。 给定四个索引,表示数组的横排索引以及纵排索引,然后就是这个范围所代表的矩形区域的和。

算法讲解

· 本题的 dp[i][j] 表示 [1][1]到dp[i][j] 所构成的矩形区域的和。

· 根据数形结合来推导出状态转移方程。

· dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + arr[i][j] - dp[i - 1][j - 1]

· 同样的,为了防止数组下标越界访问,也是从1下标开始计数。

· 利用数形结合,同样推导出该公式。

· ret = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1]

编写代码

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

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt(), q = sc.nextInt();
        // 创建一个二维前缀和数组
        long[][] dp = new long[n + 1][m + 1];
        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] + sc.nextInt() - dp[i-1][j-1];
            }
        }

        // 使用二位前缀数组
        for (int i = 0; i < q; i++) {
            int x1 = sc.nextInt(), y1 = sc.nextInt(), x2 = sc.nextInt(), y2 = sc.nextInt();
            System.out.println(dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1]);
        }
    }
}

寻找数组的中心下标

题目解析

返回一个下标,这个下标(不包括它自己)左边所有元素的和等于右边所有元素的和。

算法讲解

· 题目出现了某一个区间内的和,那应该想到使用前缀和。

· 左边所有元素的和便使用前缀和,但这个前缀和不应该包括它自身。

· 但右边所有元素的和应该使用后缀和,且这个后缀和也不应该包括它自身。

· 根据图示,前缀和数组应该从前往后遍历,公式为:f[i] = f[i - 1] + arr[i - 1],为了防止越界访问,前缀和数组的第0个位置记得初始化

· 根据图示,后缀和数组一个从后往前遍历,公式为:g[i] = g[i + 1] + arr[i + 1],为了防止越界访问,前缀和数组的第n - 1个位置记得初始化。

· 最后如果某一位置的前缀和和后缀和相同,那么该下标就满足题意。

编写代码

java 复制代码
class Solution {
    public int pivotIndex(int[] nums) {
        int n = nums.length;
        // 创建前缀和数组以及后缀和数组
        int[] f = new int[n];
        for (int i = 1; i < n; i++) 
            f[i] = f[i - 1] + nums[i - 1];

        int[] g = new int[n];
        for (int i = n - 2; i >= 0; i--)
            g[i] = g[i + 1] + nums[i + 1];

        // 使用前缀和数组以及后缀和数组
        for (int i = 0; i < n; i++) {
            if (f[i] == g[i]) 
                return i;
        }
        return -1;
    }
}

除自身以外数组的乘积

题目解析

本题表示对于当前下标,除了它自身以外的元素,返回其余元素的乘积。

算法讲解

· 这题与上题类似,只不过变成了前缀积和后缀积。

· 填完前缀积和后缀积后,之间返回它们对于下标的积即可。

编写代码

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int len = nums.length;
        // 创建前缀积数组以及后缀积数组
        int[] f = new int[len];
        f[0] = 1;
        for (int i = 1; i < len; i++) {
            f[i] = f[i - 1] * nums[i - 1];
        }

        int[] g = new int[len];
        g[len - 1] = 1;
        for (int i = len - 2; i >= 0; i--) {
            g[i] = g[i + 1] * nums[i + 1];
        }

        int[] ret = new int[len];
        // 使用前缀积数组以及后缀积数组
        for (int i = 0; i < len; i++) {
            ret[i] = f[i] * g[i];
        }
        return ret;
    }
}

好了,以上就是今天内容的全部讲解,如果有不懂的地方,随时私聊😘

我们下半部分见😁

相关推荐
IT猿手2 小时前
2025最新群智能优化算法:山羊优化算法(Goat Optimization Algorithm, GOA)求解23个经典函数测试集,MATLAB
人工智能·python·算法·数学建模·matlab·智能优化算法
夏天的味道٥3 小时前
使用 Java 执行 SQL 语句和存储过程
java·开发语言·sql
云上艺旅3 小时前
K8S学习之基础十八:k8s的灰度发布和金丝雀部署
学习·云原生·容器·kubernetes
IT、木易4 小时前
大白话JavaScript实现一个函数,将字符串中的每个单词首字母大写。
开发语言·前端·javascript·ecmascript
冰糖码奇朵4 小时前
大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解
java·数据库·sql·mysql
好教员好4 小时前
【Spring】整合【SpringMVC】
java·spring
Mr.NickJJ5 小时前
JavaScript系列06-深入理解 JavaScript 事件系统:从原生事件到 React 合成事件
开发语言·javascript·react.js
Dream it possible!5 小时前
LeetCode 热题 100_字符串解码(71_394_中等_C++)(栈)
c++·算法·leetcode
浪九天5 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
Archer1946 小时前
C语言——链表
c语言·开发语言·链表