201、【数组】leetcode ——面试题 17.05. 字母与数字(C++版本)

该文章介绍了一种算法问题,即在给定的字符串数组中找到字母和数字个数相等的最长子数组。解决方案是通过计算字符串转化为数字后的前缀和,利用哈希表存储首次出现的前缀和及其索引,然后在遍历过程中更新最长子数组的长度。文章强调了时间复杂度和空间复杂度均为O(n)。
摘要由CSDN通过智能技术生成

题目描述

在这里插入图片描述

Problem: 面试题 17.05. 字母与数字

思路

因为要找到字母和数字个数都相同的情况下,最长数组长度。那么其实就并不需要考虑具体的内容,而只需要关注字符串中的类别即可。只将字符串中看作由字母和数字两个类别组成的结构。

为了便于计算相同个数,将数字作为1,字母作为-1,将字符串中的内容进行转化。对于转化的数组,只要子数组中的元素之和为0,就能保证原字符中数字和字母的个数相同。

为了计算子数组的元素之和,便可以用前缀和的方式进行实现。前缀和常用于解决计算某段区间长度之和的问题。s[i]表示数组中0 ~ i-1之和,如果想要求i - 1 ~ j之间的区间元素之和,就让s[j + 1] - s[i]即可。而我们的目标是找到子数组元素之和为0的区间长度,而满足这一条件的便是从0 ~ n-1之中前缀和相同的
那段区间。当s[i] = s[j]的时候,此时二者之间的区间元素之和一定为0。 因此,找到i与j最大差值的情况即可。

解题方法

遍历各个字符串中构成的前缀和,使用一个哈希表存储第一次遇到的某一值的前缀和,当下次再遍历到相同前缀和时,就计算二者之间的长度之差,找到所有情况中的最大值。

复杂度

  • 时间复杂度:

添加时间复杂度, 示例: O ( n ) O(n) O(n)

  • 空间复杂度:

添加空间复杂度, 示例: O ( n ) O(n) O(n)

Code


class Solution {
public:
    vector<string> findLongestSubarray(vector<string>& array) {
        // 构建哈希表存储第一次遇到的前缀和,key:前缀和,value:下标
        unordered_map<int, int> record;
        record[0] = -1;                 // 0表示没有,为了便于后续计算,按下标为-1
        // startIndex和哈希表中的0表示一致
        int sum = 0, maxLength = 0, startIndex = -1, n = array.size();
        for(int i = 0; i < n; i++) {    
            // 找到数字就前缀和加一,找到字母就前缀和减一
            if(array[i][0] - '0' >= 0 && array[i][0] - '0' <= 9) {
                sum++;
            } else {
                sum--;
            }
            // 如果前缀和已存在,则更新最长长度;如果前缀和不存在,则在哈希表中记录
            if(record.count(sum)) {
                int firstIndex = record[sum];           // 获取第一个遇到这一前缀和的下标(前缀和的下标m对应array[0 .. m-1])
                if(i - firstIndex > maxLength) {        // 更新最长长度
                    maxLength = i - firstIndex;         
                    startIndex = firstIndex + 1;        
                }
            } else {
                record[sum] = i;
            }
        }
        // 长度为0,没有找到可以让数组和字母相等的子数组,返回空
        if(maxLength == 0)              return {};

        // 返回最长长度子数组
        return vector<string>(array.begin() + startIndex, array.begin() + startIndex + maxLength);
    }
};

参考文章:字母与数字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰阳星宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值