前缀和问题1

1.【模板】前缀和(DP34)

题目描述:
在这里插入图片描述
在这里插入图片描述

算法原理:
题目会多次给定左右边界,让我们分别计算区间内的元素和,我们可以建立一个dp数组,使用一个循环来进行填表,dp[i]就是a1到a2的元素和。这样我们求al到ar的元素和就可以直接通过dp[r]-dp[l]+nums[l]这个公式得到,还是很好理解的。
代码如下:

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int q = in.nextInt();
        long[] nums = new long[n + 1];
        long[] dp = new long[n + 1];

        for (int i = 1; i <= n; i++) {
            nums[i] = in.nextInt();
            dp[i] = dp[i - 1] + nums[i];
        }

        for (int i = 0; i < q; i++) {
            int l = in.nextInt();
            int r = in.nextInt();

            System.out.println(dp[r] - dp[l] + nums[l]);
        }
    }
}

题目链接

2.【模板】二维前缀和(DP35)

题目描述:
在这里插入图片描述
在这里插入图片描述

算法原理:
这一题和上一题是类似的,我们定义一个二维的数组dp,使用dp[i][j]来表示从(1,1)到(i,j)这个矩阵内所有元素的和,至于数组的更新可以通过dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+nums[i][j]这样的关系来更新。这样如果指定(x1,y1)到(x2,y2)这个矩阵内的元素和就是dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1],可以通过画图来帮助理解。
代码如下:

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();
        int m = in.nextInt();
        int q = in.nextInt();

        long[][] nums = new long[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++) {
                nums[i][j] = in.nextLong();
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + nums[i][j];
            }
        }

        for (int i = 0; i < q; i++) {
            int x1 = in.nextInt();
            int y1 = in.nextInt();
            int x2 = in.nextInt();
            int y2 = in.nextInt();
            System.out.println(dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1
                               - 1]);
        }
    }
}

题目链接

3. 寻找数组的中心下标(724)

题目描述:
在这里插入图片描述

算法原理:
题目要求我们去在数组中找到一个元素,使得它前面的元素和与后面的元素和相等并返回下标。至于返回最左边的下标,只需要从左边开始遍历数组即可。具体的做题方式还是维护前缀和数组和后缀和数组,使用f[i]表示nums数组0到i-1元素的和,g[i]表示nums数组i+1到n-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 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;
    }
}

题目链接

4. 除自身以外数组的乘积(238)

题目描述:
在这里插入图片描述

算法原理:
和上题是类似的,区别点就在于这一题维护的前缀和以及后缀和数组中存的都是乘积,然后最终需要将每个位置相应的值都计算一遍放到数组中返回。
代码如下:

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

        f[0] = 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];
        }

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

        return answer;
    }
}

题目链接

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值