专题四:前缀和~
前缀和模板
前缀和思想中预处理是牺牲空间,换取时间
一、【模板】前缀和
链接: DP34 【模板】前缀和
public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt(),q = in.nextInt();int[] arr = new int[n + 1];for (int i = 1; i <= n; i++) arr[i] = in.nextInt();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--;}}
二、【模板】二维前缀和
链接: DP35 【模板】二维前缀和
public static void main1(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][j - 1] + dp[i - 1][j] -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--;}}
三、寻找数组的中心下标
链接: 724. 寻找数组的中心下标
public int pivotIndex(int[] nums) {int n = nums.length;int[] f = new int[n]; f[0] = 0;int[] g = new int[n]; g[n - 1] = 0;for (int i = 1; i < n; i++)f[i] = f[i - 1] + nums[i - 1];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;}
四、除自身以外数组的乘积
链接: 238. 除自身以外数组的乘积
public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] f = new int[n]; f[0] = 1;int[] g = new int[n]; g[n - 1] = 1;for (int i = 1; i < n; i++)f[i] = f[i - 1] * nums[i - 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 的子数组
public int subarraySum(int[] nums, int k) {Map<Integer,Integer> hash = new HashMap<Integer,Integer>();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 整除的子数组
public int subarraysDivByK(int[] nums, int k) {Map<Integer,Integer> hash = new HashMap<Integer,Integer>();hash.put(0 % k,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;}
七、连续数组
链接: LCR 011. 连续数组
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)) ret = Math.max(ret,i - hash.get(sum));else hash.put(sum,i);}return ret;}
八、 矩阵区域和
链接: 1314. 矩阵区域和
public int[][] matrixBlockSum(int[][] mat, int k) {int m = mat.length,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;}
本期内容到此为止,喜欢的话请点个赞,谢谢观看!!!