算法专题四:前缀和

1.一维前缀和

题目链接:【模板】前缀和_牛客题霸_牛客网

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

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n =in.nextInt();
        int q =in.nextInt();
        int[] arr=new int[n+1];
        long[] dp=new long[n+1];
        for(int i=1;i<=n;i++){
            arr[i]=in.nextInt();
        }
        for(int i=1;i<=n;i++){
            dp[i]=dp[i-1]+arr[i];
        }
        while(q>0){
            int l=in.nextInt();
            int r=in.nextInt();
            System.out.println(dp[r]-dp[l-1]);
            q--;
        }


    }
}

2.二维前缀和

题目链接:【模板】二维前缀和_牛客题霸_牛客网

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

// 注意类名必须为 Main, 不要有任何 package xxx 信息
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];
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                arr[i][j]=in.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]-dp[i-1][j-1]+arr[i][j];
            }
        }
        
        while(q>0){
            int x1=in.nextInt(),y1=in.nextInt(),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]);
            q--;
        }
    }
}

3.寻找数组的中心下标

题目链接:724. 寻找数组的中心下标 - 力扣(LeetCode)

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

4.除自身以外数组的乘积

题目链接:238. 除自身以外数组的乘积 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n=nums.length;
        int[] d=new int[n];
        int[] b=new int[n];
        d[0]=b[n-1]=1;
        for(int i=1;i<n;i++){
            d[i]=d[i-1]*nums[i-1];
        }
        for(int i=n-2;i>=0;i--){
            b[i]=b[i+1] * nums[i+1];
        }
        int[] ret=new int[n];
        for(int i=0;i<n;i++){
            ret[i]=d[i]*b[i];
        }
        return ret;
    }
}

5.和为k的子数组

题目链接:560. 和为 K 的子数组 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer,Integer> hashMap=new HashMap<Integer,Integer>();
        int ret=0;
        int sum=0;
        hashMap.put(0,1);
        for(int x:nums){
            sum+=x;
            ret+=hashMap.getOrDefault(sum-k,0);
            hashMap.put(sum,hashMap.getOrDefault(sum,0)+1);
        }
        return ret;

    }
}

6.和可被k整除的子数组(☆)

题目链接:974. 和可被 K 整除的子数组 - 力扣(LeetCode)

首先我们讲解一下什么是同余定理

处理特殊情况

java 复制代码
class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        Map<Integer,Integer> hash=new HashMap<>();
        hash.put(0,1);
        int sum=0,ret=0;
        for(int x:nums){
            sum+=x;
            int r=(sum%k+k)%k;
            ret+=hash.getOrDefault(r,0);
            hash.put(r,hash.getOrDefault(r,0)+1);
        }
        return ret;
    }
}

7.连续数组

题目链接:525. 连续数组 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int findMaxLength(int[] nums) {
        Map<Integer,Integer> hash=new HashMap<Integer,Integer>();
        hash.put(0,-1);
        int sum=0,ret=0;
        for(int i=0;i<nums.length;i++){
            sum+=(nums[i]== 0 ? -1 : 1);
            if(hash.containsKey(sum)){
//如果该前缀和在以前出现过,说明i到以前出现时的下标差 中间的值为零
                ret=Math.max(ret,i-hash.get(sum));
            }else{
                hash.put(sum,i);
            }
        }
        return ret;
    }
}

8.矩阵区域和

题目链接:1314. 矩阵区域和 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int[][] matrixBlockSum(int[][] mat, int k) {
        int m=mat.length;
        int n=mat[0].length;
        int[][] dp=new int[m+1][n+1];
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+mat[i-1][j-1];
            }
        }
        int[][] ret=new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                int x1=Math.max(0,i-k)+1,y1=Math.max(0,j-k)+1;
                int x2=Math.min(m-1,i+k)+1,y2=Math.min(n-1,j+k)+1;
                ret[i][j]=dp[x2][y2]-dp[x2][y1-1]-dp[x1-1][y2]+dp[x1-1][y1-1];
            }
        }
        return ret;
    }
}

希望能对大家有所帮助!!!

相关推荐
IronMurphy7 小时前
【算法四十三】279. 完全平方数
算法
lee_curry7 小时前
第四章 jvm中的垃圾回收器
java·jvm·垃圾收集器
墨染天姬7 小时前
【AI】Hermes的GEPA算法
人工智能·算法
papership7 小时前
【入门级-数据结构-3、特殊树:完全二叉树的数组表示法】
数据结构·算法·链表
smj2302_796826528 小时前
解决leetcode第3911题.移除子数组元素后第k小偶数
数据结构·python·算法·leetcode
九转成圣8 小时前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
Beginner x_u8 小时前
链表专题:JS 实现原理与高频算法题总结
javascript·算法·链表
SmartRadio8 小时前
ESP32-S3 双模式切换实现:兼顾手机_路由器连接与WiFi长距离通信
开发语言·网络·智能手机·esp32·长距离wifi
laowangpython9 小时前
Rust 入门:GitHub 热门内存安全编程语言
开发语言·其他·rust·github
我叫汪枫9 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript