以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
引言----前缀和这类题一段时间没做了就容易忘记,一但忘记就呜呜呜-写不出出来,难受的,这次写出来把自己的想法记录下
主要解题思路:利用一个哈希表存储前缀和的索引,这里需要注意的是我们把0看做-1,这样做的好处是方便前缀和的使用,因为这样只要前面保存的前缀和的值(假设其索引为i)和的当前的前缀和的值一样(索引为j)那我们可以断定i到j这段区间0和1的数量是一样的---因为j的前缀和包含i的部分具体如图
解题思路
要解决这个问题,我们可以利用前缀和和哈希表的技巧。具体思路如下:
-
前缀和的定义:
-
将数组中的0视为-1,1视为1。
-
计算前缀和
presum
,表示从数组开头到当前索引的累加和。 -
如果两个索引的前缀和相同,说明这两个索引之间的子数组中0和1的数量相等。
-
-
哈希表的作用:
-
使用哈希表记录每个前缀和第一次出现的索引。
-
如果后续再次遇到相同的前缀和,说明这两个索引之间的子数组满足条件,更新最大长度。
-
-
初始化:
-
哈希表中初始化
presum = 0
的索引为-1
,表示前缀和为0的情况。class Solution { public: int findMaxLength(vector<int>& nums) { unordered_map<int,int> hash; int ret = 0; int n = nums.size(); int presum = 0; hash[0] = -1; for (int i = 0; i < n; i++) {//保存前缀和和它的索引在哈希表中---利用好前面保存的前缀和和后续继续相加找到的前缀和若相同则中间和为0 nums[i]>0?presum+=1:presum-=1; if (hash.find(presum)!=hash.end()) { ret = max(ret, i - hash[presum]); } else { hash[presum]=i; } } return ret; } };
代码解析
-
初始化:
-
hash[0] = -1
:表示前缀和为0的情况,初始索引为-1。 -
presum
:用于计算前缀和,初始值为0。
-
-
遍历数组:
-
对于每个元素,如果是1,则
presum += 1
;如果是0,则presum -= 1
。 -
检查当前
presum
是否已经存在于哈希表中:-
如果存在,说明从
hash[presum] + 1
到当前索引的子数组中0和1的数量相等,更新最大长度ret
。 -
如果不存在,将当前
presum
和索引存入哈希表。
-
-
-
复杂度分析
-
时间复杂度:遍历数组一次,时间复杂度为 O(n)。
-
空间复杂度:哈希表最多存储 n 个前缀和,空间复杂度为 O(n)。
-
返回结果:
-
最终返回
ret
,即最长的满足条件的子数组长度。总结
通过前缀和和哈希表的结合使用,我们可以高效地解决“找到最长的连续子数组,使得0和1的数量相等”的问题。这个方法不仅思路清晰,而且代码实现也相对简洁。希望本文能帮助你更好地理解这个问题及其解决方案。如果你有任何问题或建议,欢迎在评论区留言讨论。
-
-