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

这里是Themberfue

【模板】前缀和

题目解析

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

算法讲解

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

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

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

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

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

· 总结公式:left, right => dpright - dpleft - 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]);
        }
    }
}

【模板】二维前缀和

题目解析

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

算法讲解

· 本题的 dpij 表示 11到dpij 所构成的矩形区域的和。

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

· dpij = dpi - 1j + dpij - 1 + arrij - dpi - 1j - 1

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

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

· ret = dpx2y2 - dpx1 - 1y2 - dpx2y1 - 1 + dpx1 - 1y1 - 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]);
        }
    }
}

寻找数组的中心下标

题目解析

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

算法讲解

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

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

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

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

· 根据图示,后缀和数组一个从后往前遍历,公式为:gi = gi + 1 + arri + 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;
    }
}

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

我们下半部分见😁

相关推荐
caimouse1 小时前
reactos编码规范
c语言·开发语言
小雨下雨的雨3 小时前
井字棋AI机器人实现详解 - Minimax算法实战-鸿蒙PC Electron框架完成
前端·人工智能·算法·华为·electron·鸿蒙
xieliyu.5 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
明夜之约6 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee6 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Jinkxs6 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
辣机小司6 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
一条小锦吕*6 小时前
基于Spring Boot + 数据可视化 + 协同过滤算法的推荐系统设计与实现(源码+论文+部署全讲解)
spring boot·算法·信息可视化
数智工坊6 小时前
机器人运动控制:采样、优化与学习三大流派深度对比与实战
android·学习·机器人
CryptoPP6 小时前
快速对接东京证券交易所API数据:实战指南与代码示例
开发语言·人工智能·windows·python·信息可视化·区块链