算法: 前缀和题目练习

news2024/12/23 0:43:29

文章目录

  • 前缀和题目练习
    • 前缀和
    • 二维前缀和
    • 寻找数组的中心下标
    • 除自身以外数组的乘积
    • 和为 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 会变小
                // 因此要写 else
                hash.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.coloradmin.cn/o/2204302.html

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

相关文章

“国货户外TOP1”凯乐石签约实在智能,RPA助力全域电商运营自动化提效

近日&#xff0c;国货第一户外品牌KAILAS凯乐石与实在智能携手合作&#xff0c;基于实在智能“取数宝”自动化能力&#xff0c;打通运营数据获取全链路&#xff0c;全面提升淘宝、天猫、抖音等平台的运营效率与消费者体验&#xff0c;以自动化能力驱动企业增长。 KAILAS凯乐石…

雨晨 24H2 正式版 Windows 11 iot ltsc 2024 适度 26100.2033 VIP2IN1

雨晨 24H2 正式版 Windows 11 iot ltsc 2024 适度 26100.2033 VIP2IN1 install.wim 索引: 1 名称: Windows 11 IoT 企业版 LTSC 2024 x64 适度 (生产力环境推荐) 描述: Windows 11 IoT 企业版 LTSC 2024 x64 适度 By YCDISM 2024-10-09 大小: 15,699,006,618 个字节 索引: 2 …

Jenkins常见问题处理

Jenkins操作手册 读者对象&#xff1a;生产环境管理及运维人员 Jenkins作用&#xff1a;项目自动化构建部署。 一、登陆 二、新增用户及设置权限 2.1&#xff1a;新增用户 点击Manager Jenkins → Manager Users → Create User 2.2&#xff1a;权限 点击Manager Jenkins…

互联网线上融合上门洗衣洗鞋小程序,让洗衣洗鞋像点外卖一样简单

随着服务创新的风潮&#xff0c;众多商家已巧妙融入预约上门洗鞋新风尚&#xff0c;并携手洗鞋小程序&#xff0c;开辟线上蓝海。那么&#xff0c;这不仅仅是一个小程序&#xff0c;它究竟蕴含着哪些诱人好处呢&#xff1f; 1. 无缝融合&#xff0c;双线共赢&#xff1a;小程序…

Corel VideoStudio Ultimate 会声会影2025旗舰版震憾来袭,会声会影2025旗舰版最低系统要求

软件介绍 会声会影2025旗舰版全名&#xff1a;Corel VideoStudio Ultimate 2025&#xff0c;相信做视频剪辑的朋友都认识它&#xff0c;会声会影是一款强大的视频剪辑编辑软件&#xff0c;运用数百种拖放滤镜、效果、图形、标题和过渡&#xff0c;探索新奇好玩的新增面部追踪贴…

彩族相机内存卡恢复多种攻略:告别数据丢失

在数字时代&#xff0c;相机内存卡作为我们存储珍贵照片和视频的重要媒介&#xff0c;其数据安全性显得尤为重要。然而&#xff0c;意外删除、错误格式化、存储卡损坏等情况时有发生&#xff0c;导致数据丢失&#xff0c;给用户带来不小的困扰。本文将详细介绍彩族相机内存卡数…

【万字长文】Word2Vec计算详解(三)分层Softmax与负采样

【万字长文】Word2Vec计算详解&#xff08;三&#xff09;分层Softmax与负采样 写在前面 第三部分介绍Word2Vec模型的两种优化方案。 【万字长文】Word2Vec计算详解&#xff08;一&#xff09;CBOW模型 markdown行 9000 【万字长文】Word2Vec计算详解&#xff08;二&#xff0…

初级网络工程师之从入门到入狱(五)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 网络工程师从入门到入狱 前言一、链路聚合1.1、手动进行链路聚合1.1.1、 拓扑图&#xff1a;1.1.2、 LSW11.1.3、 LSW2 1.2、…

5.C语言基础入门:数据类型、变量声明与创建详解

C语言基础入门&#xff1a;数据类型、变量声明与创建详解 C语言往期系列文章目录 往期回顾&#xff1a; C语言是什么&#xff1f;编程界的‘常青树’&#xff0c;它的辉煌你不可不知VS 2022 社区版C语言的安装教程&#xff0c;不要再卡在下载0B/s啦C语言入门&#xff1a;解锁…

Elasticsearch 索引数据预处理

pipeline 在文档写入 ES 之前&#xff0c;对数据进行预处理&#xff08;ingest&#xff09;工作通过定义 pipeline 和 processors 实现。 注意&#xff1a;数据预处理必须在 Ingest node 节点处理&#xff0c;ES 默认所有节点都是 Ingest node。 如果需要禁用 Ingest &#x…

Java中的拦截器、过滤器及监听器

过滤器&#xff08;Filter&#xff09;监听器&#xff08;Listener&#xff09;拦截器&#xff08;Interceptor&#xff09;关注点web请求系统级别参数、对象Action&#xff08;部分web请求&#xff09;如何实现函数回调事件Java反射机制&#xff08;动态代理&#xff09;应用场…

《大道平渊》· 廿贰 —— 杀心篇:独立人格的形成

《大道平渊》 独立人格的形成&#xff0c;在杀心的过程中会越来越完备。 在这个漫长的过程中&#xff0c;你会一次次击碎自己固有的三观&#xff0c;慢慢再修复你的三观。 . 不要认为一个人的明白&#xff0c;都是恍然大悟&#xff0c;都是碰到了高人指点。 并不是这样的&a…

使用 Raspberry Pi Pico W 的基于 MQTT 的分布式网络自适应估计

英文论文标题&#xff1a;MQTT based Adaptive Estimation over Distributed Network using Raspberry Pi Pico W 中文论文标题&#xff1a;使用 Raspberry Pi Pico W 的基于 MQTT 的分布式网络自适应估计 作者信息&#xff1a; Prantaneel DebnathAnshul GusainParth Sharm…

46 C 语言文件的打开与关闭、写入与读取函数:fopen、fclose、fputc、fputs、fprintf、fgetc、fgets、fscanf

目录 1 文件的存储形式 2 打开文件——fopen() 函数 2.1 功能描述 2.2 函数原型 2.3 文件打开方式&#xff08;模式&#xff09; 3 关闭文件——fclose() 函数 3.1 功能描述 3.2 函数原型 4 常见的文件写入方式 4.1 fputc() 函数 4.1.1 功能描述 4.1.2 函数原型 4…

第四范式发布全新一代文档数字化管理平台Smart Archive 2.0

产品上新 Product Release 今日&#xff0c;第四范式正式推出全新一代文档数字化管理平台——Smart Archive 2.0。该产品基于第四范式自研的文档处理大模型&#xff0c;实现零样本下对企业文档的精准识别及信息提取。文档处理大模型利用二十多个行业&#xff0c;上百种场景下的…

【华为】默认路由配置

1.配置接入层&#xff1a; LSW1&#xff08;LSW3同理&#xff09;: vlan batch 10 20 in g0/0/1 port link-type ac port default vlan 10 in g0/0/2 port link-type ac port default vlan 20 in g0/0/24 port link-type tr port tr allow-pass vlan 10 20 2.配置汇聚层&#x…

Spring Boot 集成 LiteFlow 实现业务流程编排

LiteFlow 是一款轻量级的流程编排框架,它允许开发者通过简单的配置方式,将复杂的业务流程分解为多个独立的节点,然后通过定义规则来编排节点,达到解耦业务逻辑、提高代码可维护性的目的 1. LiteFlow 的基本概念 在 LiteFlow 中,主要有以下几个概念: 节点 (Node):代表一…

2015年国赛高教杯数学建模C题月上柳梢头解题全过程文档及程序

2015年国赛高教杯数学建模 C题 月上柳梢头 月上柳梢头&#xff0c;人约黄昏后”是北宋学者欧阳修的名句&#xff0c;写的是与佳人相约的情景。请用天文学的观点赏析该名句&#xff0c;并进行如下的讨论&#xff1a;   1. 定义“月上柳梢头”时月亮在空中的角度和什么时间称为…

SKG未来健康校招社招入职测评:综合能力及性格问卷SHL测评题库

SKG未来健康科技股份有限公司在校招和社招过程中使用的SHL测评题库主要考察应聘者的综合能力和性格特征。以下是对这些测评的简要分析&#xff1a; 综合能力测评&#xff1a; 测评时间&#xff1a;46分钟&#xff08;实际答题时间36分钟&#xff09; 题目数量&#xff1a;30题…

多jdk版本环境下,jenkins系统设置需指定JAVA_HOME环境变量

一、背景 由于不同项目对jdk版本的要求不同&#xff0c;有些是要求jdk11&#xff0c;有些只需要jdk8即可。 而linux机器上安装jdk的方式又多种多样&#xff0c;最后导致jenkins打包到底使用的是哪个jdk&#xff0c;比较混乱。 1、java在哪 > whereis java java: /usr/bin/…