前缀和第二弹

简介: 前缀和第二弹

力扣560.和为k的子数组

子数组经典暴力解法:枚举全部位置,因为取值为可能为负

首先把前缀和,和出现的次数都存储一下,一般前缀和就出现一次,然后往后找,如果前缀和-k就说明有一段数组是等于sum-k

class Solution {
    public int subarraySum(int[] nums, int k) {
        //前缀和  字符串组成sum次数
    Map<Integer,Integer>hash=new HashMap<>();
    hash.put(0,1);
    //ret统计最终结果,sum表示前一个位置的前缀和
    int sum=0;
    int ret=0;
    for(int m:nums){
        //sum+=表示当前位置前缀和
        sum+=m;
        //统计结果
        ret+=hash.getOrDefault(sum-k,0);
        hash.put(sum,hash.getOrDefault(sum,0)+1);
 
    }
    return ret;
    }
}

力扣974.和可被K整除的子数组

引入同余定理

2.java(负数%正数)的结果以及修正

负%正=负->修正 a%p+p,但是假如a是一个正数,那么正数%p然后再加上一个p就变成了多了个p,所以再次%. 也就是说(a%p+p)%p

我们这里求的是前面的x存储了次数,然后看后面的是否有和他相同的,假如有相同的那么就ret表示次数,先从hash里面找前面有没有相同的,然后把前面相同的值加上

假如说前缀和-这个之前的前缀和也可以整除,那么说明a,b可以整除

class Solution {
    public int subarraysDivByK(int[] nums, int k) {
     Map<Integer,Integer> hash=new HashMap<>();
     hash.put(0,1);
     int sum=0;
     int ret=0;
     for(int x:nums){
         //sum是前缀和
         sum+=x;
         //r是表示前缀和的余数
         int r=(sum%k+k)%k;
         ret+=hash.getOrDefault(r,0);
         hash.put(r,hash.getOrDefault(r,0)+1);
     }
 
return ret;
    }
}

力扣525.连续数组

解法:

前缀和+哈希表

1.哈希表里面存什么(因为我们要知道子数组的长度,所以需要用下标来计算长度)

hash<int,int>前缀和,下标

2.什么时候存入哈希表

使用完之后,丢进哈希表

3.如果有重复的<sum,i>怎么办

只保留前面的那一对<sum,i>

4.默认的前缀和为0的情况,如何存储

假如是【0,1】我们改成[-1,1]这时候前缀和是0,我们的长度设置要是-1,他的长度才能是2

hash[0]=-1

5.长度如何计算

 public int findMaxLength(int[] nums) {
        //我们只关心长度,只要下标,才能计算长度
        //一个是前缀和,一个就是下标
        Map<Integer,Integer>hash=new HashMap<>();
        hash.put(0,-1);
        int sum=0;
        int ret=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]==0){
                sum+=-1;
            }else{
            sum+=1;//计算当前位置前缀和
            }
            //现在前面找一个值也等于sum
            if(hash.containsKey(sum))
            //那么此时的下标,就是我们要找的下标
            ret=Math.max(ret,i-hash.get(sum));
            //看你存不存在当前sum,要是不存在,就放进去即可
            else  hash.put(sum,i);
        }
        return ret;
    }

力扣1314.矩阵区域和

是一个上面加上一个左边,但是上面和左边都包括你的斜上方,所以减去一个斜上方,再去加上当前位置的数值。

我们该如何求出我们想要的那个点的值呢

首先我们先把我们想要的区域找好

下标映射关系:

为了方便处理边界情况 我们二维dp都是从1开始计数,但是我们的mat是从0开始计数

所以我们,需要多加一列dp[m+1][n+1]

当我门dp表想填写[i][j]->mat[i-1][j-1],当我们使用dp表的时候,填写ret,使用x1,x2的时候,应该x+1,y+1的位置,修改方式,我们求矩阵下标x1,x2的时候+1即可。


相关文章
|
传感器 Linux
在Linux中使用libmodbus库进行Modbus RTU主从机通信
Modbus RTU是一种常见的工业通信协议,用于在自动化系统中传输数据。libmodbus是一个流行的C库,用于在Linux系统上实现Modbus通信。本文将介绍如何使用libmodbus库在Linux上创建Modbus RTU主从机通信的示例代码。
5852 0
|
Ubuntu
Ubuntu Server 20.04 LTS下载及安装教程
Ubuntu Server 20.04 LTS下载及安装教程
4354 0
Ubuntu Server 20.04 LTS下载及安装教程
|
数据采集 自然语言处理 搜索推荐
图文详解 DFS 和 BFS | 算法必看系列知识二十四
深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷宫),搜索引擎,爬虫等,也频繁出现在高频面试题中。
35633 6
图文详解 DFS 和 BFS | 算法必看系列知识二十四
|
存储 Unix 编译器
汇编语言----X86汇编指令
汇编语言----X86汇编指令
743 2
|
11月前
|
监控 安全 网络协议
|
存储 算法 Java
【DFS(深度优先搜索)详解】看这一篇就够啦
本文介绍了深度优先搜索(DFS)算法及其应用。DFS从某个顶点出发,深入探索图的每条路径,直到无法前进为止,然后回溯。文章详细解释了DFS的基本思想,并通过示例图展示了其执行过程。此外,文中还探讨了三种枚举方式:指数型枚举、排列型枚举和组合型枚举,并提供了具体的代码实现。最后,文章通过几道练习题帮助读者更好地理解和应用DFS算法。
8581 19
【DFS(深度优先搜索)详解】看这一篇就够啦
|
11月前
|
移动开发 网络协议 C语言
详解 httptools 模块,一个 HTTP 解析器
详解 httptools 模块,一个 HTTP 解析器
263 0
|
监控 编译器 C++
【代码讲解】【C/C++】获取文件最后修改的时间(系统时间)
【代码讲解】【C/C++】获取文件最后修改的时间(系统时间)
533 0
|
开发者
CMake 命令行使用指南:创建构建目录与编译项目
CMake 命令行使用指南:创建构建目录与编译项目
680 0