【程序员面试金典】面试题 17.05. 字母与数字

【程序员面试金典】面试题 17.05. 字母与数字

    • 题目描述
    • 解题思路

题目描述

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

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

示例 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:最直观的想法是,由于只有字母和数字,且要求子序列中字母和数字的个数相同,即字母个数与数字个数相差为0,那么不妨将字母转化为1,将数字转化为-1,这样问题就转换为求元素和为0的最长子数组,进而转换为起始下标和结束下标的前缀和相等。使用哈希表记录每个前缀和以及其第一次出现的下标,使用sum记录当前前缀和,使用maxl记录当前最长长度,使用startindex记录最长前缀和起始下标。首先遍历数组,然后判断当前元素是否为字母,如果是则使sum加一,反之使得sum减一,接着判断哈希表中sum是否出现过,如果没有则把当前下标i以及前缀和sum存入哈希表,反之则取出sum第一次出现的下标firstindex以及当前下标i,使用i-firstindex得到长度,并与maxl进行比较,如果当前更大则更新maxl以及起始下标分别为i-firstindex和firstindex+1,最后遍历完后判断maxl是否大于0,如果不是则返回空数组,反之则返回[startindex,startindex+maxl]直接的数组元素即可。

vector findLongestSubarray(vector& array) 
{
   //字母个数与数字个数相差为0 字母转化为1 数字转化为-1
   //转化为元素和为0的最长子数组 即起始下标和结束下标的前缀和相等
   //使用哈希表记录每个前缀和和第一次出现的下标
   unordered_map index;
   index[0]=-1;
   int sum=0;
   int maxl=0;
   int startindex=-1;
   int n=array.size();
   for(int i=0;imaxl)
        {
          //更新maxl和startindex
          maxl=i-firstIndex;
          //数据范围是[startindex,i]
          startindex=firstIndex+1;
        }
     }
     //否则记录第一次出现的位置
     else
       index[sum]=i;
   }
   if(maxl==0)
     return {};
return vector (array.begin()+startindex,array.begin()+startindex+maxl);
}

总结:将只有两种且相等的问题转换为-1和1进而求前缀和。isalpha用于判断当前字符是否为字母。

你可能感兴趣的:(程序员面试金典,面试,职场和发展)