1. 2次元プレフィックス合計アルゴリズム

プレフィックスとテンプレート

1 次元のプレフィックスの合計:

import java.util.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt(),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();
            dp[i] = dp[i - 1] + arr[i];
        }
        while(q > 0) {
    
    
            int l = scan.nextInt(),r = scan.nextInt();
            System.out.println(dp[r] - dp[l - 1]);
            q--;
        }
    }
}

2 次元のプレフィックスの合計:

import java.util.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt(),m = scan.nextInt(),q = scan.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] = scan.nextInt();
                dp[i][j] = arr[i][j] + dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];
            }
        }
        while(q > 0) {
    
    
            int x1 = scan.nextInt(),y1 = scan.nextInt();
            int x2 = scan.nextInt(),y2 = scan.nextInt();
            System.out.println(dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1]);
            q--;
        }
    }
}

724. 配列の中心インデックスを見つける

整数配列 nums を指定して、配列の中心インデックスを計算してください。

配列の中央の添字は配列の添字であり、左側のすべての要素の合計は右側のすべての要素の合計と等しくなります。

中央の添字が配列の左端にある場合、添字の左側には要素がないため、左側の数値の合計は 0 とみなされます。これは、配列の右端にある中央の添字にも当てはまります。

配列に複数の中央添字がある場合は、左に最も近い添字が返される必要があります。配列に中心添字がない場合は -1 を返します。
ここに画像の説明を挿入

class Solution {
    
    
    public int pivotIndex(int[] nums) {
    
    
        int n = nums.length;
        int[] f = new int[n];
        int[] g = new int[n];

        for(int i = 1;i < n;i ++) {
    
    
            f[i] = f[i - 1] + nums[i - 1];
        }
        for(int j = n - 2;j >= 0;j--) {
    
    
            g[j] = g[j + 1] + nums[j + 1];
        }
        for(int i = 0;i < n;i++) {
    
    
            if(f[i] == g[i]) {
    
    
                return i;
            }
        }
        return -1;
    }
}

238. それ自体以外の配列の積

整数配列 nums を指定すると、配列の Answer を返します。answer[i] は、nums[i] を除く nums のすべての要素の積に等しくなります。

タイトル データは、配列 nums 内のすべてのプレフィックス要素と任意の要素のサフィックスの積が 32 ビット整数の範囲内であることを保証します。

除算を使用せず、この問題を O(n) 時間の計算量で解決してください。
ここに画像の説明を挿入

class Solution {
    
    
    public int[] productExceptSelf(int[] nums) {
    
    
        int n = nums.length;
        int[] f = new int[n];
        int[] g = new int[n];
        f[0] = 1;
        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[] ret = new int[n];
        for(int i = 0;i < n;i++) {
    
    
            ret[i] = f[i] * g[i];
        }
        return ret;
    }
}

560. K のサブ配列の合計

整数配列 nums と整数 k が与えられた場合、この配列内で合計が k となる連続した部分配列の数を数えて返します。
ここに画像の説明を挿入

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;
    }
}

974. K で割り切れる部分配列の合計

整数配列 nums と整数 k を指定すると、合計が k で割り切れる (連続した空でない) 部分配列の数を返します。

サブ配列は配列の連続した部分です。
ここに画像の説明を挿入

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;
    }
}

525. 連続した配列

バイナリ配列 nums を指定して、同じ数の 0 と 1 を含む最も長く連続する部分配列を見つけ、その部分配列の長さを返します。
ここに画像の説明を挿入

class Solution {
    
    
    public int findMaxLength(int[] nums) {
    
    
        Map<Integer,Integer> hash = new HashMap<>();
        hash.put(0,-1); //默认存在一个前缀和为0的情况

        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. マトリックス領域と

mxn 行列 mat と整数 k が与えられた場合、行列の答えを返してください。ここで、各answer[i][j] は、次の条件を満たすすべての要素 mat[r][c] の合計です。

i - k <= r <= i + k、j - k <= c <= j + k および (r, c) は行列内にあります。
ここに画像の説明を挿入

class Solution {
    
    
    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] = mat[i - 1][j - 1] + dp[i - 1][j] + dp[i][j - 1] 
                - dp[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;
                int y1 = Math.max(0,j - k) + 1;
                int x2 = Math.min(m - 1,i + k) + 1;
                int y2 = Math.min(n - 1,j + k) + 1;
                ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1-1][y1-1];
            }
        }
        return ret;
    }
}

おすすめ

転載: blog.csdn.net/buhuisuanfa/article/details/131843864