【算法专题】前缀和(附图解、代码)

前言

本文主要是前缀和的文章,如果有什么需要改进的地方还请大佬指出⛺️

作者简介:大家好,我是青衿
☁️博客首页:CSDN主页放风讲故事
每日一句:努力一点,优秀一点

在这里插入图片描述

目录

文章目录

  • 前言
  • **目录**
      • 1. 统计范围内的元音字符串数
      • 2.二维区域和检索 - 矩阵不可变
  • 文章末尾


1. 统计范围内的元音字符串数

leetcode2559
给你一个下标从 0 开始的字符串数组 words 以及一个二维整数数组 queries 。

每个查询 queries[i] = [li, ri] 会要求我们统计在 words 中下标在 li 到 ri 范围内(包含 这两个值)并且以元音开头和结尾的字符串的数目。

返回一个整数数组,其中数组的第 i 个元素对应第 i 个查询的答案。

注意:元音字母是 ‘a’、‘e’、‘i’、‘o’ 和 ‘u’ 。

示例 1:
输入:words = [“aba”,“bcb”,“ece”,“aa”,“e”], queries = [[0,2],[1,4],[1,1]]
输出:[2,3,0]
解释:以元音开头和结尾的字符串是 “aba”、“ece”、“aa” 和 “e” 。
查询 [0,2] 结果为 2(字符串 “aba” 和 “ece”)。
查询 [1,4] 结果为 3(字符串 “ece”、“aa”、“e”)。
查询 [1,1] 结果为 0 。
返回结果 [2,3,0] 。
示例 2:
输入:words = [“a”,“e”,“i”], queries = [[0,2],[0,1],[2,2]]
输出:[3,2,1]
解释:每个字符串都满足这一条件,所以返回 [3,2,1] 。

提示:
1 <= words.length <= 105
1 <= words[i].length <= 40
words[i] 仅由小写英文字母组成
sum(words[i].length) <= 3 * 105
1 <= queries.length <= 105
0 <= queries[j][0] <= queries[j][1] < words.length
思路:
1.初速化prefixSums[0],然后遍历求出prefixSum的值
2.求任意区间i到j的和,可以表示为prefixSum[j] -prefixSum[I -1]

代码如下:

class Solution {
    public int[] vowelStrings(String[] words, int[][] queries) {
        int n = words.length;
        int[] prefixSums = new int[n];
        prefixSums[0] = isVowelString(words[0]) ? 1 : 0;
        for (int i = 1; i < n; i++) {
            int value = isVowelString(words[i]) ? 1 : 0;
            prefixSums[i] = prefixSums[i - 1] + value;
        }
        int q = queries.length;
        int[] ans = new int[q];
        for (int i = 0; i < q; i++) {
            int start = queries[i][0], end = queries[i][1];
            if(start == 0) {
                ans[i] = prefixSums[end];
                continue;
            }
            ans[i] = prefixSums[end] - prefixSums[start - 1];
        }
        return ans;
    }

    public boolean isVowelString(String word) {
        return isVowelLetter(word.charAt(0)) && isVowelLetter(word.charAt(word.length() - 1));
    }

    public boolean isVowelLetter(char c) {
        return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    }
}

2.二维区域和检索 - 矩阵不可变

leetcode304
给定一个二维矩阵 matrix,以下类型的多个请求:

计算其子矩形范围内元素的总和,该子矩阵的 左上角 为 (row1, col1) ,右下角 为 (row2, col2) 。
实现 NumMatrix 类:

NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进行初始化
int sumRegion(int row1, int col1, int row2, int col2) 返回 左上角 (row1, col1) 、右下角 (row2, col2) 所描述的子矩阵的元素 总和 。

示例 1:
【算法专题】前缀和(附图解、代码)_第1张图片

输入:
[“NumMatrix”,“sumRegion”,“sumRegion”,“sumRegion”]
[[[[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,0,1,7],[1,0,3,0,5]]],[2,1,4,3],[1,1,2,2],[1,2,2,4]]
输出:
[null, 8, 11, 12]

解释:
NumMatrix numMatrix = new NumMatrix([[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,0,1,7],[1,0,3,0,5]]);
numMatrix.sumRegion(2, 1, 4, 3); // return 8 (红色矩形框的元素总和)
numMatrix.sumRegion(1, 1, 2, 2); // return 11 (绿色矩形框的元素总和)
numMatrix.sumRegion(1, 2, 2, 4); // return 12 (蓝色矩形框的元素总和)

提示:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 200
-105 <= matrix[i][j] <= 105
0 <= row1 <= row2 < m
0 <= col1 <= col2 < n
最多调用 104 次 sumRegion 方法
思路:
1,二维前缀和,初始化preSum[0][0],以及第0行preSum[0][i]和第0列preSum[i][0]
2.从1,1开始遍历求出矩形的所有元素之和,即 preSum[i][j] = 左边前缀和+上面前缀和-左上角前缀和 + matrix[i][j];
3.注意preSum[i][j]的定义,以及左上角 (row1, col1) 、右下角 (row2, col2)
【算法专题】前缀和(附图解、代码)_第2张图片

代码如下:

public class NumMatrix {
    int[][] preSum;
    public NumMatrix(int[][] matrix) {
        int m = matrix.length;
        if (m > 0) {
            int n = matrix[0].length;
            this.preSum = new int[m][n];
            preSum[0][0] = matrix[0][0];
            for (int i = 1; i < m; i++) {
                preSum[i][0] = preSum[i - 1][0] + matrix[i][0];
            }
            for (int i = 1; i < n; i++) {
                preSum[0][i] = preSum[0][i - 1] + matrix[0][i];
            }
            for (int i = 1; i < m; i++) {
                for (int j = 1; j < n; j++) {
                    preSum[i][j] = matrix[i][j] + preSum[i - 1][j] + preSum[i][j - 1] - preSum[i - 1][j - 1];
                }
            }
        }
    }
    public int sumRegion(int row1, int col1, int row2, int col2) {
        if (row1 == 0 && col1 == 0) {
            return preSum[row2][col2];
        } else if (row1 == 0) {
            return preSum[row2][col2] - preSum[row2][col1-1];
        } else if (col1 == 0) {
            return preSum[row2][col2] - preSum[row1-1][col2];
        }
        return preSum[row2][col2] - preSum[row1-1][col2] - preSum[row2][col1-1] + preSum[row1-1][col1-1];
    }
}

文章末尾

在这里插入图片描述

你可能感兴趣的:(算法)