前缀和(7)_连续数组

devtools/2024/10/18 3:23:58/

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

前缀和(7)_连续数组

收录于专栏【经典算法练习】
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 题目链接 :

2. 题目描述 :

3. 解法(一维前缀和) :

    算法思路 :

   示例说明:

    代码展示 :

    结果分析:

 


1. 题目链接 :

OJ链接: 连续数组

2. 题目描述 :

给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。

示例 1:

输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。

示例 2:

输入: nums = [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。

提示:

  • 1 <= nums.length <= 105
  • nums[i] 不是 0 就是 1

3. 解法(一维前缀和) :

    算法思路 :

转换 0 和 1:

将 0 视作 - 1,而 1 保持不变。这意味着在计算前缀和时,0 会减少总和。
这样,当某段区间内的 0 和 1 数量相同时,前缀和将回到相同的值。

计算前缀和:

遍历数组时,维护一个变量 sum 用来表示当前的前缀和。
如果在某个位置的 sum 值与之前某个位置的 sum 值相同,说明从这两个位置之间的元素(即子数组)中,0 和 1 的数量相等。

使用哈希表记录前缀和的索引:

使用一个哈希表 dp 来存储每个前缀和第一次出现的索引。
初始化 dp[0] = -1,表示前缀和为 0 的情况下,虚拟的索引是 - 1,这有助于处理从数组起始位置开始的有效子数组。

判断条件:

在遍历数组时,每当计算新的前缀和 sum:
        如果 sum 已经在 dp 中存在(即 dp.count(sum) 为真),这意味着从 dp[sum] + 1 到当前索引 i 的这段区间中,0 和 1 的数量相等。
        通过计算当前索引 i 与 dp[sum] 的差值得到这段子数组的长度:i - dp[sum]。

   示例说明:

假设有一个数组 nums = [0, 1, 0, 1],我们可以按以下步骤分析前缀和的变化:

初始状态:

dp = { 0: -1 }
sum = 0
ret = 0

遍历数组:

i = 0, nums[0] = 0:
        sum = 0 + (-1) = -1
        dp[-1] 不存在,所以将 dp[-1] = 0。
i = 1, nums[1] = 1 :
    sum = -1 + 1 = 0
    dp[0] 已存在,表示从 dp[0] + 1 到 i 的子数组有相同数量的 0 和 1,长度为 1 - (-1) = 2,更新 ret = 2。

 i = 2, nums[2] = 0 :
    sum = 0 + (-1) = -1
    dp[-1] 已存在,长度为 2 - 0 = 2,ret 不变。

i = 3, nums[3] = 1 :
    sum = -1 + 1 = 0
    dp[0] 已存在,长度为 3 - (-1) = 4,更新 ret = 4。

    代码展示 :

class Solution {
public:int findMaxLength(vector<int>& nums) {unordered_map<int, int> dp;dp[0] = -1;int sum = 0, ret = 0;for(int i = 0; i < nums.size(); i++){sum += nums[i] == 0 ? -1 : 1;if(dp.count(sum)) ret = max(ret, i - dp[sum]);else dp[sum] = i;} return ret;}
};

 

    结果分析:

时间复杂度和空间复杂度
时间复杂度 :O(n),其中n 是数组的长度。我们只遍历数组一次。
空间复杂度 :O(n),在最坏情况下,哈希表可能存储所有的前缀和。

 


http://www.ppmy.cn/devtools/119168.html

相关文章

4G模组SIM卡电路很简单,但也要注意这些坑

上次水SIM卡相关的文章&#xff0c;还是上一次&#xff1b; 上一篇文章里吹牛说&#xff0c;跟SIM卡相关的问题还有很多&#xff0c;目的是为下一篇文章埋下伏笔&#xff1b;伏笔埋是埋下了&#xff0c;但如果债老是不还&#xff0c;心里的石头就总悬着&#xff0c;搞不好老板…

如何使用GitHub Desktop管理GitLab库

不管是新手还是老手&#xff0c;Github Desktop都是在苹果系统和Windows系统上管理与创建项目的不错的方式&#xff0c;GitHub Desktop都能够让在GitHub上的工作流更为简单快捷。 注意&#xff0c;以下步骤只支持原版的GitHub Desktop 第一步 从这下载GitHub Desktop打开你的G…

利用redis实现分布式定时任务

如果是微服务&#xff0c;两个服务都有定时&#xff0c;那么就出问题了&#xff0c;但是上分布式定时任务框架太麻烦怎么办&#xff0c;那么就用redis加个锁&#xff0c;谁先抢到锁谁执行 整个工具类 import org.springframework.beans.factory.annotation.Autowired; import …

Spring Boot 进阶-Spring Boot 如何实现自定义的过滤器详解

在上一篇文章中我们讲解了关于拦截器的相关内容,并且通过一个防抖的例子来讲解了拦截器在实际开发中的使用。这篇文章我们为大家带来的就是关于过滤器的相关内容的分享。下面我们首先来介绍一下什么是过滤器。 什么是过滤器? 过滤器Filter,是Servlet技术中最常用的技术,开…

Motion open Heart 详细动画化开放式心脏解剖

详细和动画的心脏直视解剖。 具有真实的运动和精确的心动周期动画。 包括真实阀门动画序列。 配备高清纹理2048x2048和高清法线贴图,可在教育和游戏方面获得更好、更真实的效果。为(VR)虚拟现实场景和增强现实(AR)做好准备。 下载:​​Unity资源商店链接资源下载链接 …

C++ 排序算法

快速排序 思想&#xff1a; 分而治之&#xff0c;或者说递归&#xff0c;即大问题拆解成类似的小问题&#xff0c;把所有的小问题解决&#xff0c;就解决了大问题&#xff1b; 应用在快排&#xff08;默认从小到大排序&#xff09;上&#xff0c;就是取一基准点&#xff0c;遍…

0基础跟德姆(dom)一起学AI 机器学习02-KNN算法

【理解】KNN算法思想 K-近邻算法&#xff08;K Nearest Neighbor&#xff0c;简称KNN&#xff09;。比如&#xff1a;根据你的“邻居”来推断出你的类别 KNN算法思想&#xff1a;如果一个样本在特征空间中的 k 个最相似的样本中的大多数属于某一个类别&#xff0c;则该样本也属…

从零到 Go 语言开发:你可能需要了解下 5 个关键技巧

你有没有想过,要在 Go 语言中开发一个简单的 Web 应用其实没那么难?或者说,你是不是在学习 Go 语言的时候,常常觉得各种框架和概念让人头疼?今天,我就带你一步一步看看 Go 语言 Web 开发中最核心的几个点,揭开它那看似复杂的面纱,实际操作起来,可能比你想象中简单得多…