目录
[1. 一维前缀和(easy)](#1. 一维前缀和(easy))
[2. 二维前缀和(medium)](#2. 二维前缀和(medium))
[27. 寻找数组的中心下标(easy)](#27. 寻找数组的中心下标(easy))
[28. 除自身以外数组的乘积(medium)](#28. 除自身以外数组的乘积(medium))
1. 一维前缀和(easy)
题目链接:
解题思路:
使用前缀和数组
dp,其中dp[i]表示从第 1 个元素到第 i 个元素的和。预处理后,区间[l, r]的和可以通过dp[r] - dp[l-1]快速求得。
Java 代码:
java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int q = scan.nextInt();
int[] arr = new int[n + 1];
long[] dp = new long[n + 1];
for (int i = 1; i <= n; i++) {
arr[i] = scan.nextInt();
}
for (int i = 1; i <= n; i++) {
dp[i] = dp[i - 1] + arr[i];
}
while (q-- > 0) {
int l = scan.nextInt();
int r = scan.nextInt();
System.out.println(dp[r] - dp[l - 1]);
}
}
}
2. 二维前缀和(medium)
题目链接:
解题思路:
定义
dp[i][j]为从(1,1)到(i,j)的矩形区域和。递推公式为:
dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + arr[i][j]查询子矩阵
(x1,y1)到(x2,y2)的和为:
dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]
Java 代码:
java
import java.util.Scanner;
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];
long[][] dp = 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();
}
}
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();
int 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]);
}
}
}
27. 寻找数组的中心下标(easy)
题目链接:
解题思路:
分别计算前缀和数组
lsum和后缀和数组rsum,遍历每个位置i,若lsum[i] == rsum[i]则返回i。
Java 代码:
java
class Solution {
public int pivotIndex(int[] nums) {
int n = nums.length;
int[] lsum = new int[n];
int[] rsum = new int[n];
for (int i = 1; i < n; i++) {
lsum[i] = lsum[i - 1] + nums[i - 1];
}
for (int i = n - 2; i >= 0; i--) {
rsum[i] = rsum[i + 1] + nums[i + 1];
}
for (int i = 0; i < n; i++) {
if (lsum[i] == rsum[i]) return i;
}
return -1;
}
}
28. 除自身以外数组的乘积(medium)
题目链接:
解题思路:
分别计算前缀积数组
lprod和后缀积数组rprod,则ret[i] = lprod[i] * rprod[i]。
Java 代码:
java
class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] lprod = new int[n];
int[] rprod = new int[n];
lprod[0] = 1;
rprod[n - 1] = 1;
for (int i = 1; i < n; i++) {
lprod[i] = lprod[i - 1] * nums[i - 1];
}
for (int i = n - 2; i >= 0; i--) {
rprod[i] = rprod[i + 1] * nums[i + 1];
}
int[] ret = new int[n];
for (int i = 0; i < n; i++) {
ret[i] = lprod[i] * rprod[i];
}
return ret;
}
}