当前位置: 首页 > news >正文

力扣精选算法100道—— 连续数组(前缀和专题)

连续数组(前缀和专题)

目录

🚩了解题意

🚩算法原理

❗为什么hash设置成<0,-1>键值对

❗与和为K的子数组比较hash的键值对

🚩代码实现


🚩了解题意

我们看到给定数组里面只有0和1,我们要找到一个连续的子数组具有相同数量的0和1,那么我们想想,如果我们给0代替成-1,那么-1 1 -1 1是不是等于0是不是相当于找到了具有相同数量的0和1了。

所以 我们首先要想到 将0改成-1 ,然后找到相同的0和1的数量就转换成在数组中最长的子数组中和为0.

这一题和 和为K的子数组 很像 ——和为0的子数组(我们只需要将0改成-1即可)


🚩算法原理

该函数的主要目的是找到nums中的一个最长的连续子数组,该子数组中0和1的数量相等。它使用了一个哈希表hash来记录当前累积和首次出现的位置,以便在后续遍历中可以计算当前累积和与首次出现位置之间的距离,从而得到最长的满足条件的子数组长度。

还是利用哈希+前缀和思路。但是这一题我们需要考虑到几个细节。

我们先给过程分析一下吧

  1. 创建一个无序哈希表hash,用于存储累积和及其首次出现的位置。初始化时将累积和为0的位置设为-1,这样方便后续计算。
  2. 初始化两个整数变量sumret,分别用于存储当前累积和和最长满足条件的子数组长度。
  3. 使用循环遍历nums中的每个元素,对累积和进行更新。如果当前元素为0,则累积和加上-1,否则加上1。
  4. 在每次更新累积和后,检查哈希表中是否已经记录了当前累积和。如果已经记录,则计算当前位置与首次出现位置的距离,并更新最长子数组长度ret。否则,将当前累积和及其位置记录到哈希表中。
  5. 最后,返回最长子数组长度ret作为结果。

这段代码的时间复杂度为O(n),其中n是输入向量nums的长度。


这里有几个细节问题

为什么累积和为0的位置设为-1,我们根据一个情况来阐述吧

<0,-1>键值对,0代表前缀和,-1代表下标。

❗为什么hash设置成<0,-1>键值对

在这段代码中,将累积和为0的位置设为-1的目的是为了在计算最长子数组长度时能够正确处理从数组开头开始的子数组。

在遍历数组时,累积和为0意味着从数组开始到当前位置的子数组中0和1的数量相等。因此,如果在后续的遍历中再次遇到累积和为0,那么说明中间这段子数组中0和1的数量仍然相等。

如果没有将累积和为0的位置设为-1,而是设为0,那么在计算距离时可能会得到错误的结果。因为累积和为0的情况可能出现在数组的第一个位置,此时距离为当前位置减去0,会导致计算出的距离比实际子数组长度小1。

因此,将累积和为0的位置设为-1可以避免这种情况,确保计算出的最长子数组长度是正确的。


❗与和为K的子数组比较hash的键值对

hash[0] = 1 的目的是在处理前缀和时确保能够正确统计到和为k的子数组的数量。这是一个常用的技巧,主要是为了处理当前缀和恰好等于k的情况。

具体来说,hash 这个哈希表用于统计前缀和出现的次数。在初始化时,将累积和为0的次数设置为1是为了确保能够正确处理累积和等于k的情况。

考虑这样一种情况,如果数组中存在一个子数组的和正好等于k,那么这个子数组的前缀和减去k就等于0。因此,在遍历数组时,当遇到一个前缀和sum时,如果之前已经有一个前缀和sum - k存在,那么说明从那个前缀和到当前位置的子数组和正好为k。

举个例子,假设有数组 nums = [1, 2, 3],而 k = 3。在遍历过程中,前缀和依次为1、3、6,此时对于前缀和为3,前缀和为0的情况正好存在,这意味着从数组开头到当前位置的子数组和为3,满足条件。

因此,初始化时将 hash[0] = 1 是为了确保能够正确处理这种情况。


和为K的子数组:<0,1> 在和为K的子数组中0代表前缀和,1代表前缀和出现的次数

和为0的子数组:这一题<0,-1> 在和为0的子数组中 0代表前缀和,-1代表下标的位置。


🚩代码实现

class Solution {
public:int findMaxLength(vector<int>& nums) {unordered_map<int,int>hash;hash[0]=-1;int sum=0,ret=0;int dest=0;for(int i=0;i<nums.size();i++){sum+=nums[i]==0?-1:1;//如果sums[i]==0就改成-1,否则就是1if(hash.count(sum)) ret=max(ret,i-hash[sum]);else hash[sum]=i;//这里记录的是长度}return ret;}
};

我们会一直一直在一起哒!

http://www.lryc.cn/news/296954.html

相关文章:

  • flutter 国内源
  • 第九个知识点:内部对象
  • Android 车载应用开发之车载操作系统
  • Qt PCL学习(文章链接汇总)
  • 安卓动态链接库文件体积优化探索实践
  • [Java][算法 哈希]Day 01---LeetCode 热题 100---01~03
  • 【每日一题】LeetCode——链表的中间结点
  • k8s 部署java应用 基于ingress+jar包
  • 深度学习技巧应用36-深度学习模型训练中的超参数调优指南大全,总结相关问题与答案
  • “探索AJAX:前端与后端数据交互的利器“
  • 【5G NR】移动通讯中使用的信道编解码技术
  • 用Python Tkinter打造的精彩连连看小游戏【附源码】
  • nvm安装node后,npm无效
  • spring boot(2.4.x 开始)和spring cloud项目中配置文件application和bootstrap加载顺序
  • 5-2、S曲线计算【51单片机+L298N步进电机系列教程】
  • SQL 注入 - http头注入之UA头注入探测
  • 学习数据结构和算法的第5天
  • Android 11 访问 Android/data/或者getExternalCacheDir() root方式
  • Linux探秘之旅:透彻理解路径、命令与系统概念
  • 哈希算法 c语言
  • 新版MQL语言程序设计:组合模式的原理、应用及代码实现
  • 代码随想录算法训练营第25天 | 216.组合总和III ,17.电话号码的字母组合
  • Rust 第一个rust程序Hello Rust️
  • 高斯消去法 | LU分解 | PA=LU分解(MatLab)
  • Linux笔记之expect和bash脚本监听输出并在匹配到指定字符串时发送中断信号
  • 项目02《游戏-12-开发》Unity3D
  • 记一次面试题
  • Rust入门2——随机数
  • c#: 表达式树的简化
  • 13. UE5 RPG限制Attribute的值的范围以及生成结构体