LeetCode 算法:字母与数字

234 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 24 天,点击查看活动详情

字母与数字

原题地址

给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。

返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。

示例 1:

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

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

示例 2:

输入: ["A","A"]

输出: []

提示:

  • array.length <= 100000

思路分析

  1. 题目中要求最长的子数组中包含相同数量的字母和数字,那么我们将字母当作-1,将数字当作1来简化问题;那也就是找到最长的字符串的子数组的和为 0 即可;
  2. 使用 map 来存储子数组的和,如果 map 中不存在子数组的和,那么将其 index 记录下来,否则来判断 当前下标与子数组和对应的下标的差值跟 end-start 大小,即判断新产生的子数组的长度与记录下来的子数组的长度,然后更新 start 和 end 值;
  3. 最后我们取 array 中的 start+1 到 end+1 的子数组。

["A","1","B","C","D","2","3","4","E","5","F","G","6","7","H","I","J","K","L","M"] 来看下代码执行的过程:

itemindexcountmapstartend
A01{'0': -1, '1': 0}00
110{ '0': -1, '1': 0 }-11
B21{ '0': -1, '1': 0 }-11
C32{ '0': -1, '1': 0, '2': 3 }-11
D43{ '0': -1, '1': 0, '2': 3, '3': 4 }-11
252{ '0': -1, '1': 0, '2': 3, '3': 4 }-11
361{ '0': -1, '1': 0, '2': 3, '3': 4 }06
470{ '0': -1, '1': 0, '2': 3, '3': 4 }-17
E81{ '0': -1, '1': 0, '2': 3, '3': 4 }-17
590{ '0': -1, '1': 0, '2': 3, '3': 4 }-19
F101{ '0': -1, '1': 0, '2': 3, '3': 4 }-19
G112{ '0': -1, '1': 0, '2': 3, '3': 4 }-19
6121{ '0': -1, '1': 0, '2': 3, '3': 4 }012
7130{ '0': -1, '1': 0, '2': 3, '3': 4 }-113
H141{ '0': -1, '1': 0, '2': 3, '3': 4 }-113
I152{ '0': -1, '1': 0, '2': 3, '3': 4 }-113
J163{ '0': -1, '1': 0, '2': 3, '3': 4 }-113
K174{ '0':-1,'1':0,'2':3,'3':4,'4':17 }-113
L185{ '0':-1,'1':0,'2':3,'3':4,'4':17,'5':18 }-113
M196{ '0':-1,'1':0,'2':3,'3':4,'4':17,'5':18,'6':19 }-113

AC 代码

/**
 * @param {string[]} array
 * @return {string[]}
 */
var findLongestSubarray = function(array) {
    let count = 0
    const map = {}
    let start = 0, end = 0
    map[0] = -1
    array.forEach((item, index) => {
        count += isNaN(Number(item)) ? 1 : -1
        if (map[count] !== undefined) {
            if (index - map[count] > end - start) {
                end = index
                start = map[count]
            }
        } else {
            map[count] = index
        }
    })
    return array.slice(start + 1, end + 1)
};

结果:

  • 执行结果: 通过
  • 执行用时:196 ms, 在所有 JavaScript 提交中击败了24.39%的用户
  • 内存消耗:60.6 MB, 在所有 JavaScript 提交中击败了31.71%的用户
  • 通过测试用例:45 / 45

END