LeetCode——面试题 17.05. 字母与数字

一、题目

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

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-longest-subarray-lcci/description/

二、C++解法

我的思路及代码

前缀和

由于给的数组只有字母和数字两种,于是我们可以将字母和数字进行转化,遇到数字算 +1 ,遇到字母算 -1 ,然后来计算前缀和。我们用哈希表来记录某前缀和最早出现的位置,当某前缀和再次出现时就用当前的位置减去他最早出现的位置,即可得到子数组长度,我们采用 maxLen 来存储当前最大的子数组长度,更新maxLen时,同时更新最大子数组的起始坐标,最后返回即可。

class Solution {
public:
    vector<string> findLongestSubarray(vector<string>& array) {
        int size = array.size();
        int prefix[size];
        int start=-1;
        int maxLen=0;
        vector<string> ans;
        unordered_map<int,int> map;
        map[0] = -1;
        prefix[0] = array[0][0]>='0'&&array[0][0]<='9'?1:-1;
        
        for(int i=1;i<size;i++){
            if(array[i][0]>='0'&&array[i][0]<='9')
                prefix[i] = prefix[i-1]+1;
            else
                prefix[i] = prefix[i-1]-1;
        }

        for(int i=0;i<size;i++){
            if(map.count(prefix[i])){
                if(maxLen<i-map[prefix[i]]){
                    maxLen = i-map[prefix[i]];
                    start = map[prefix[i]];
                }
            }else
                map[prefix[i]] = i;
        }
        ans.assign(array.begin()+start+1,array.begin()+start+maxLen+1);
        return ans;
    }
};
  • 时间复杂度:O(n),其中 n 是数组的长度。需要遍历数组一次计算符合要求的最长子数组的长度与开始下标,对于数组中的每个元素的操作时间都是 O(1),因此遍历时间是 O(n),生成结果数组需要 O(n) 的时间
  • 空间复杂度:O(n),其中 n 是数组的长度。哈希表需要 O(n) 的空间。注意返回值不计入空间复杂度

官方参考代码

和我的思路差不多,但是写法仍然有值得学习的地方

class Solution {
public:
    vector<string> findLongestSubarray(vector<string>& array) {
        unordered_map<int, int> indices;
        indices[0] = -1;
        int sum = 0;
        int maxLength = 0;
        int startIndex = -1;
        int n = array.size();
        for (int i = 0; i < n; i++) {
            if (isalpha(array[i][0])) {
                sum++;
            } else {
                sum--;
            }
            if (indices.count(sum)) {
                int firstIndex = indices[sum];
                if (i - firstIndex > maxLength) {
                    maxLength = i - firstIndex;
                    startIndex = firstIndex + 1;
                }
            } else {
                indices[sum] = i;
            }
        }
        if (maxLength == 0) {
            return {};
        }
        return vector<string>(array.begin() + startIndex, array.begin() + startIndex + maxLength);
    }
};
  • 时间复杂度:O(n),其中 n 是数组的长度。需要遍历数组一次计算符合要求的最长子数组的长度与开始下标,对于数组中的每个元素的操作时间都是 O(1),因此遍历时间是 O(n),生成结果数组需要 O(n) 的时间
  • 空间复杂度:O(n),其中 n 是数组的长度。哈希表需要 O(n) 的空间。注意返回值不计入空间复杂度

你可能感兴趣的:(力扣,leetcode,算法)