算法: 前缀和题目练习

文章目录

  • 前缀和题目练习
    • 前缀和
    • 二维前缀和
    • 寻找数组的中心下标
    • 除自身以外数组的乘积
    • 和为 K 的子数组
    • 和可被 K 整除的子数组
    • 连续数组
    • 矩阵区域和


前缀和题目练习

前缀和

在这里插入图片描述
自己写出来了~

坑:

  • 数据太大,要用long.
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt();int q = in.nextInt();long[] arr = new long[n];long[] dp = new long[n+1];for(int i=0;i<n;i++) {arr[i] = in.nextLong();dp[i+1] = arr[i] + dp[i];}while(q-- > 0){int l = in.nextInt();int r = in.nextInt();System.out.println(dp[r]-dp[l-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 q = in.nextInt();long[] arr = new long[n+1];long[] dp = new long[n+1];for(int i=1;i<=n;i++) {arr[i] = in.nextLong();dp[i] = arr[i] + dp[i-1];}while(q-- > 0){int l = in.nextInt();int r = in.nextInt();System.out.println(dp[r]-dp[l-1]);}}
}

二维前缀和

在这里插入图片描述
自己写出来了~

在往二维数组存数据的时候,内层循环用错了,应该用 m,而不是 n.
在最后计算结果的时候,最开始没有算的太明白.

dp[i][j] 计算的是它左上方所有元素的和(包括自己)~

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[][] arr = 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++) {arr[i][j]=in.nextInt();}}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];// System.out.printf("%d ",dp[i][j]);}// System.out.println();}while(q-- > 0) {int x1 = in.nextInt();int y1 = in.nextInt();int x2 = in.nextInt();int y2 = in.nextInt();System.out.println(dp[x2][y2]-dp[x2][y1-1]-dp[x1-1][y2]+dp[x1-1][y1-1]);}}
}

寻找数组的中心下标

在这里插入图片描述
我的第一反应是想用一个sum计算所有元素的和,然后除 2 得到 target,接着再使用滑动窗口寻找这个target , 发现行不通,因为数组中可能有负数和0~

自己写出来了~

坑:

  • 题目说: 如果有结果,返回最靠左的那一个~
class Solution {public int pivotIndex(int[] nums) {int[] dp = new int[nums.length];dp[nums.length - 1] = nums[nums.length - 1];for (int i = nums.length - 2; i >= 0; i--) {dp[i] = dp[i + 1] + nums[i];}int sum = 0;for (int i = 0; i < nums.length; i++) {sum += nums[i];if (sum == dp[i])return i;}return -1;}
}

除自身以外数组的乘积

在这里插入图片描述
自己写出来了~
优化前(空间复杂度 O(N) ):

class Solution {public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] dp1 = new int[n];int[] dp2 = new int[n];int[] ret = new int[n];dp1[0] = nums[0];for (int i = 1; i < n; i++) {dp1[i] = dp1[i - 1] * nums[i];}dp2[n - 1] = nums[n - 1];for (int i = n - 2; i >= 0; i--) {dp2[i] = dp2[i + 1] * nums[i];}ret[0] = dp2[1];ret[n - 1] = dp1[n - 2];for (int i = 1; i < n - 1; i++) {ret[i] = dp1[i - 1] * dp2[i + 1];}return ret;}
}

优化后(空间复杂度 O(1) ):

class Solution {public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] ret = new int[n];// 计算前面元素的乘积ret[0] = nums[0];for (int i = 1; i < n - 1; i++) {ret[i] = ret[i - 1] * nums[i];}ret[n - 1] = ret[n - 2];// 用sum表示后面元素的乘积int sum = nums[n - 1];for (int i = n - 2; i > 0; i--) {ret[i] = ret[i - 1] * sum;sum *= nums[i];}ret[0] = sum;return ret;}
}

和为 K 的子数组

在这里插入图片描述
因为数组中的元素有小于等于0的数,所以不能使用滑动窗口来解题~

没写出来.

  1. 在 [0 , i - 1] 区间内,有多少个前缀和等于 sum[i] - k
  2. 使用哈希表<前缀和,出现次数>
    在这里插入图片描述
  • 1,2 都懂, 到 3 的时候有点晕.
    class Solution {public int subarraySum(int[] nums, int k) {int n = nums.length;HashMap<Integer, Integer> hash = new HashMap<>();int ret = 0;int sum = 0;hash.put(0, 1);for (int i = 0; i < n; i++) {sum += nums[i];ret += hash.getOrDefault(sum - k, 0);hash.put(sum, hash.getOrDefault(sum, 0) + 1);}return ret;}}

和可被 K 整除的子数组

在这里插入图片描述
没写出来,但是写了个大概,就差一点,
就差 sum = (sum % k + k) % k; 这一句话…

遇到取余就满头包~

每日LeetCode,974. 和可被 K 整除的子数组

写这道题需要知道两个前置知识.

  1. 同余定理
    如果 (a - b) % n == 0 那么我们可以得到一个结论: a % n == b % n.

  2. 修正负数取模的结果
    为了防止出现负数的情况,可以使用 (a % n + n) % n 的形式保证输出结果为正.

    public int subarraysDivByK(int[] nums, int k) {int sum = 0;int ret = 0;int n = nums.length;HashMap<Integer, Integer> hash = new HashMap<>();hash.put(0, 1);for (int i = 0; i < n; i++) {sum += nums[i];sum = (sum % k + k) % k;ret += hash.getOrDefault(sum, 0);hash.put(sum, hash.getOrDefault(sum, 0) + 1);}return ret;}

连续数组

在这里插入图片描述
这一次 HashMap 中存的就不是数字出现的次数了,而是数字出现的下标.

class Solution {public int findMaxLength(int[] nums) {int ret = 0;int n = nums.length;HashMap<Integer,Integer> hash = new HashMap<>();int sum = 0;hash.put(0,-1);for(int i=0;i<n;i++) {sum += nums[i] == 0?-1:1;if(hash.containsKey(sum)) {ret = Math.max(ret,i - hash.get(sum));}else {// 当不包含 sum 时,放进hash中// 当 hash 中已经包含 sum 时,不必再放入// ret = i - hash.get(sum)// 我们要求的是最大值,因此hash.get(sum)越小越好,// 而新 put 进来的下标i 一定没有 之前的下标小// 也就是说新的hash.get(sum)比旧的hash.get(sum)大 // 用一句话概括:// 当 hash 中已经包含 sum 时,此时再更新i的话 ret 会变小// 因此要写 elsehash.put(sum,i);}}return ret;}
}

矩阵区域和

在这里插入图片描述
坑;

  • 范围容易找错
    在这里插入图片描述

  • 如果善用 Math 方法更好一点~

class Solution {public int[][] matrixBlockSum(int[][] mat, int k) {int m = mat.length;int n = mat[0].length;int[][] ret = new int[m][n];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];}}for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {int a = Math.min(i+k+1,m);int b = Math.min(j+k+1,n);int c = Math.max(i-k+1,1);int d = Math.max(j-k+1,1);ret[i][j] = dp[c-1][d-1] - dp[c-1][b] - dp[a][d-1] + dp[a][b];}}return ret;}
}

本文到这里就结束啦~

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/55877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue中用echarts做一个躺着的柱状图

在 Vue 中集成 ECharts 并绘制一个躺着的柱状图&#xff08;即横向的柱状图&#xff09;&#xff0c;你可以通过设置 ECharts 的 bar 类型&#xff0c;并配置 xAxis 和 yAxis 来实现。下面是一个完整的 Vue 示例代码。 示例代码&#xff1a; <template><div id"…

《C++编程新探索:实现高效视频拼接算法》

在当今数字化时代&#xff0c;视频内容的创作和处理变得越来越重要。视频拼接作为一种常见的视频处理技术&#xff0c;能够将多个视频片段组合成一个连续的视频&#xff0c;为视频创作者和用户带来了更多的可能性。本文将探讨如何在 C中实现高效的视频拼接算法&#xff0c;为开…

数据结构与算法JavaScript描述练习------第3章列表

1. 增加一个向列表中插入元素的方法&#xff0c;该方法只在待插元素大于列表中的所有元素时才执 行插入操作。这里的大于有多重含义&#xff0c;对于数字&#xff0c;它是指数值上的大小&#xff1b;对于字母&#xff0c;它 是指在字母表中出现的先后顺序。 function isGreate…

【element-tiptap】如何引进系统中的字体?

源码地址&#xff1a; https://github.com/Leecason/element-tiptap 源码中给出的字体如下 可以看到&#xff0c;咱们日常需要的黑体、微软雅黑等都没有&#xff0c;所以这篇文章来探索一下怎么加字体。 另外呢&#xff0c;肯定有小伙伴发现&#xff0c;这个按钮点击的时候&am…

IDEA 配置 Git 详解

本文将介绍在IntelliJ IDEA 中如何配置Git 没有安装配置 Git 的可以参考我的这篇文章&#xff1a;安装配置 Git 一、操作环境及准备 1.win 10 2.已安装且配置了Git 3.有Gitee账户 4.安装了IntelliJ IDEA 2023.2.1 5.全程联网 二、配置步骤 2.1 配置git 1.采用全局设置&…

OpenCV视频I/O(18)视频写入类VideoWriter之初始化 VideoWriter 对象的函数open()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 初始化或重新初始化视频编写器。 该方法打开视频编写器。参数与构造函数 VideoWriter::VideoWriter 中的相同。 cv::VideoWriter::open() 函数用…

C++继承与菱形继承(一文了解全部继承相关基础知识和面试点!)

目的减少重复代码冗余 Class 子类(派生类) &#xff1a; 继承方式 父类&#xff08;基类&#xff09; 继承方式共有三种&#xff1a;公共、保护、私有 父类的私有成员private无论哪种继承方式都不可以被子类使用 保护protected权限的内容在类内是可以访问&#xff0c;但是在…

息肉检测数据集 yolov5 yolov8适用于目标检测训练已经调整为yolo格式可直接训练yolo网络

息肉检测数据集 yolov5 yolov8格式 息肉检测数据集介绍 数据集概述 名称&#xff1a;息肉检测数据集&#xff08;基于某公开的分割数据集调整&#xff09;用途&#xff1a;适用于目标检测任务&#xff0c;特别是内窥镜图像中的息肉检测格式&#xff1a;YOLO格式&#xff08;边…

设计一个OAuth2认证系统:支持第三方登录的实用指南

设计一个OAuth2认证系统:支持第三方登录的实用指南 引言 在现代Web应用中,用户认证是一个至关重要的环节。OAuth2作为一种开放标准,允许用户通过第三方服务进行身份验证,简化了用户登录流程,同时提高了安全性。本文将详细介绍如何设计一个支持第三方登录的OAuth2认证系统…

wenserver中 一些常见的 错误码

EINTR 是 Linux 系统中定义的一个错误码&#xff0c;代表“被信号中断”。当一个系统调用在执行过程中被一个信号处理函数中断时&#xff0c;这个系统调用会立即返回错误&#xff0c;并且 errno 被设置为 EINTR。 举个例子 read函数是阻塞的 现在没有数据要读 我们read一直阻…

【3dgs】总结3DGS与NeRF如何重塑SLAM24年4月最新进展

【3dgs】总结3DGS与NeRF如何重塑SLAM&#xff01; 1. 摘要2. 简洁3. 背景3.1 Existing SLAM Surveys3.2 progress in Radiance Field Theory3.3.1 NeRF3.3.2 3dgs3.4 数据集 4 数据集4.1 SLAM3.1 RGB-D SLAM方法3.1.1 基于NeRF风格的RGB-D SLAM3.1.2 基于3DGS风格的 RGB-D SLAM…

React(一) 认识React、熟悉类组件、JSX书写规范、嵌入变量表达式、绑定属性

文章目录 一、初始React1. React的基本认识2. Hello案例2.1 三个依赖2.2 渲染页面2.3 hello案例完整代码 二、类组件1. 封装类组件2. 组件里的数据3. 组件里的函数 (重点)4. 案例练习(1) 展示电影列表 三、JSX语法1. 认识JSX2. JSX书写规范及注释3. JSX嵌入变量作为子元素4. JS…

小猿口算脚本

实现原理&#xff1a;安卓adb截图传到电脑&#xff0c;然后用python裁剪获得两张数字图片&#xff0c;使用ddddocr识别数字&#xff0c;比较大小&#xff0c;再用adb命令模拟安卓手势实现>< import os import ddddocr from time import sleep from PIL import Imagedef …

遍历有向图链路(DFS算法)- 优化版

在上一节基础上&#xff0c;去除了节点的pre集合&#xff0c;只保留节点next的结合&#xff0c;对数据模型进行了优化&#xff0c;实现思想做了优化。 有向图示例&#xff1a; 基本思路 构建有向图数据模型校验有向图不能出现回路&#xff0c;即当前节点不能出现在历史链路中首…

连续点击三次用户

有用户点击日志记录表 t2_click_log&#xff0c;包含user_id(用户ID),click_time(点击时间)&#xff0c;请查询出连续点击三次的用户数&#xff0c; 连续点击三次&#xff1a;指点击记录中同一用户连续点击&#xff0c;中间无其他用户点击&#xff1b; CREATE TABLE t2_click…

Unity实现自定义图集(三)

以下内容是根据Unity 2020.1.0f1版本进行编写的   1、实现编辑器模式下进游戏前Pack全部自定义图集 同Unity的图集一样,Unity的编辑器模式会在进游戏前把全部的SpriteAtlas都打一次图集,如图: 我们也实现这样的效果。 首先需要获取全部的图集路径。因为目前使用的是以.…

【数据结构】6道经典链表面试题

目录 1.返回倒数第K个节点【链接】 ​代码实现 2.链表的回文结构【链接】 代码实现 3.相交链表【链接】 代码实现 4.判断链表中是否有环【链接】 代码实现 常见问题解析 5.寻找环的入口点【链接】 代码实现1 ​代码实现2 6.随机链表的复制【链接】 代码实现 1.…

如何进行数据中心负载测试的自动化?

数据中心负载测试的自动化是一种通过使用软件工具和脚本来模拟大量用户访问数据中心的过程&#xff0c;以评估其性能、稳定性和可扩展性的方法。以下是进行数据中心负载测试自动化的一些建议&#xff1a; 市场上有许多负载测试工具可供选择&#xff0c;如LoadRunner、JMeter、…

如何防止按钮重复提交

在前端开发中&#xff0c;防止按钮重复提交是一个常见的需求&#xff0c;可以避免因用户重复点击导致的多次请求发送&#xff0c;从而影响服务器性能或导致数据错误。下面介绍几种常见的方法&#xff0c;并给出相应的示例&#xff1a; 1. 禁用按钮 在用户提交表单后&#xff…

【力扣算法题】每天一道,健康生活

2024年10月8日 参考github网站&#xff1a;代码随想录 1.二分查找 leetcode 视频 class Solution { public:int search(vector<int>& nums, int target) {int left 0;int right nums.size()-1;while(left<right){int middle (leftright)/2;if(nums[middle] …