【算法】——前缀和(矩阵区域和详解,文末附)

阿华代码,不是逆风,就是我疯

你们的点赞收藏是我前进最大的动力!!

希望本文内容能够帮助到你!!

目录

一:前缀和模版

二:前缀和模版2

三:寻找数组的中心下标

四:除自身以外数组的乘积

五:和为K的子数组

六:和被k整除的子数组

七:连续数组

八:矩阵区域和


一:前缀和模版

【模板】前缀和_牛客题霸_牛客网

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

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //1:获取输入
        int n = in.nextInt() , q = in.nextInt();//长度为n的数组,q次查询
        int[] arr = new int[n+1];
        for(int i = 1 ; i <= n ; i++){
            arr[i] = in.nextInt();
        }

        //2:创建dp数组
        long[] dp = new long[n+1]; 
        for(int i = 1 ; i <= n ; i++){
            dp[i] = dp[i-1] + arr[i];
        }

        while(q > 0){
            int l = in.nextInt() , 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);
        // 注意 hasNext 和 hasNextLine 的区别
       int n = in.nextInt() , m = in.nextInt() , q = in.nextInt();
        
        //arr数组
       long[][] arr = 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();
        }
       }

       //copy创建一个dp数组

       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();
        long result = dp[x2][y2] - dp[x2][y1-1] - dp[x1-1][y2] + dp[x1-1][y1-1];
        System.out.println(result);
        q--;
       }
    }
}

三:寻找数组的中心下标

724. 寻找数组的中心下标 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int pivotIndex(int[] nums) {
        int n = nums.length;
        //前缀和数组
        int[] f = new int[n];
        f[0] = 0;
        for(int i = 1 ; i < n ; i++){
            f[i] = f[i-1] + nums[i-1];
        }   
        //后缀和数组
        int[] g = new int[n];
        g[n-1] = 0;
        for(int i = n-2 ; i >= 0 ; i--){
            g[i] = g[i+1] + nums[i+1];
        }
        int result = Integer.MAX_VALUE;
        for(int i = 0 ; i < n ; i++){
            if(f[i] == g[i]){
                result = Math.min(result,i);
            }
        }
        if(result == Integer.MAX_VALUE){
            return -1;
        }else{
            return result;
        }

    }
}

四:除自身以外数组的乘积

238. 除自身以外数组的乘积 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;

        //前缀积
        int[] f = new int[n];
        f[0] = 1;
        for(int i=1 ; i<n ; i++ ){
            f[i] = f[i-1]*nums[i-1];
        }

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

        int[] answer = new int[n];
        for(int i = 0 ; i < n ; i++){
            answer[i] = f[i]*g[i];
        }
        return answer;
    }
}

五:和为K的子数组

560. 和为 K 的子数组 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int subarraySum(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;
            ret += hash.getOrDefault(sum-k,0);
            hash.put(sum,hash.getOrDefault(sum,0)+1);
        }
        return ret;
        
    }
}

六:和被k整除的子数组

974. 和可被 K 整除的子数组 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        Map<Integer,Integer> hashMap = new HashMap<Integer,Integer>(); 
        hashMap.put(0 % k , 1);//默认有一个前缀和=0

        int sum = 0;//前缀和
        int ret = 0;//用来计数
        for(int x : nums){
            sum += x;
            int remainder = (sum % k + k) % k;
            ret += hashMap.getOrDefault(remainder,0);
            hashMap.put(remainder,hashMap.getOrDefault(remainder,0)+1);
        }

        
        return ret;
    }
}

七:连续数组

525. 连续数组 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int findMaxLength(int[] nums) {
        
        for(int i = 0 ; i < nums.length ; i++){
            if(nums[i] == 0){
                nums[i] = -1;
            }
        }
        Map<Integer,Integer> hash = new HashMap<>();
        hash.put(0,-1);
        int sum = 0 , ret = 0;
        for(int i = 0 ; i < nums.length ; i++){
            sum += nums[i];
            if(hash.containsKey(sum)){
                int old = hash.get(sum);
                int tem = i-old;
                ret = Math.max(ret,tem);
            }else{
                hash.put(sum,i);
            }

        }
        return ret;
    }
}

八:矩阵区域和

1314. 矩阵区域和 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int[][] matrixBlockSum(int[][] mat, int k) {
        int m = mat.length , n = mat[0].length;

        //1:初始化dp前缀和数组
        int[][] dp = new int[m+1][n+1];
        for(int i = 1 ; i < m+1 ; i++){
            for(int j = 1 ; j < n+1 ; j++){
                dp[i][j] = dp[i-1][j] + dp[i][j-1] -dp[i-1][j-1] + mat[i-1][j-1];
            }
        }

        //2:处理前缀和数组
        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(i+k,m-1)+1 , y2 = Math.min(j+k,n-1)+1;
                ret[i][j] = dp[x2][y2] - dp[x2][y1-1] -dp[x1-1][y2] + dp[x1-1][y1-1];
            }
        }
        return ret;
    



    }
}
相关推荐
醉卧沙场丶8 分钟前
RedisTemplate执行lua脚本及Lua 脚本语言详解
开发语言·lua
Linux运维老纪15 分钟前
Go语言之十条命令(The Ten Commands of Go Language)
服务器·开发语言·后端·golang·云计算·运维开发
野生派蒙17 分钟前
排序算法:冒泡排序
java·数据结构·算法·排序算法
济南小草根19 分钟前
JavaScript学习记录10
开发语言·javascript·学习
小万编程20 分钟前
【2025最新计算机毕业设计】基于SpringBoot+Vue教研听课管理系统(高质量源码,提供文档,免费部署到本地)
java·spring boot·计算机毕业设计·java毕业设计·java毕设源码·web毕业设计
鲤籽鲲22 分钟前
C# in 参数修饰符的使用
开发语言·c#
啾啾Fun29 分钟前
[java基础]LinkedList源码粗析
java·开发语言
白露与泡影30 分钟前
2025 年春招互联网大厂226 道 Java 高级岗面试题
java·开发语言
晨辉软件35 分钟前
晨辉面试抽签和评分管理系统之三:考生批量抽签
算法·面试
“抚琴”的人40 分钟前
C#—Task异步的常用方法及TaskFactory工厂类详解
开发语言·c#