leetcode
leetcode 2851 ~ 2900
字母与数字

字母与数字

难度:

标签:

题目描述

Given an array filled with letters and numbers, find the longest subarray with an equal number of letters and numbers.

Return the subarray. If there are more than one answer, return the one which has the smallest index of its left endpoint. If there is no answer, return an empty arrary.

Example 1:

Input: ["A","1","B","C","D","2","3","4","E","5","F","G","6","7","H","I","J","K","L","M"]

Output: ["A","1","B","C","D","2","3","4","E","5","F","G","6","7"]

Example 2:

Input: ["A","A"]

Output: []

Note:

  • array.length <= 100000

代码结果

运行时间: 82 ms, 内存: 33.1 MB


解释

方法:

此题解采用前缀和和哈希表的方法来找到包含相同数量字母和数字的最长子数组。首先,定义一个变量prefix_sum作为前缀和,当遇到数字时增加1,遇到字母时减少1。这样,每个位置的prefix_sum值反映了从数组开始到该位置数字和字母的数量差。使用哈希表prefix_index_dict来存储每个前缀和第一次出现的位置。遍历数组,对于每个元素,如果当前前缀和已经在哈希表中存在,则说明从上一次该前缀和出现的位置到当前位置的子数组中字母和数字的数量相等。通过比较并更新最长长度max_len,记录下最长子数组的开始位置。如果最终max_len为0,说明没有找到符合条件的子数组,返回空数组;否则根据记录的开始位置和长度返回子数组。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在处理前缀和时数字增加1而字母减少1?这样的设计有什么特别的原因吗?
在这个问题中,我们需要找到一个字母和数字数量相等的子数组。为了追踪字母和数字的数量差异,我们使用前缀和的方法。通过将数字视为+1,字母视为-1,前缀和就可以表示从数组开始到当前位置为止数字和字母的数量差。如果在某个位置前缀和为0,这意味着从开始到这个位置的子数组中字母和数字的数量完全相等。因此,通过这种设计,我们可以方便地通过前缀和的变化来追踪和定位数量相等的子数组。
🦆
在哈希表中记录前缀和第一次出现的位置的目的是什么?如何通过这个信息找到满足条件的最长子数组?
记录前缀和第一次出现的位置的目的是为了在之后遇到相同的前缀和时,能够迅速找到最早出现这个前缀和的位置。如果在数组的某个后续位置我们再次遇到相同的前缀和,这意味着从最初记录的位置到这个后续位置之间的子数组中,字母和数字的增减抵消了,即这部分子数组中字母和数字的数量相等。通过这种方式,我们可以用当前的索引减去哈希表中记录的索引来计算出这个子数组的长度,并持续更新我们找到的最长的满足条件的子数组。
🦆
在题解中提到,如果前缀和在哈希表中已存在,则可以确定一个字母和数字数量相等的子数组。这种方法是如何确保子数组的字母和数字数量确实相等的?
当我们在遍历数组时,每次通过增加1或减少1来更新前缀和,这反映了从数组开始到当前元素为止,数字和字母的总数量差。当我们在哈希表中找到一个已经存在的前缀和时,这意味着从哈希表中记录的位置到当前位置的前缀和增减彼此抵消了。换句话说,这两个位置之间的子数组中,字母和数字的增减数相等,因此它们的数量也必然相等。这就是为什么当我们发现相同的前缀和时可以确定找到了一个数量相等的子数组。

相关问题