题目:
- 给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。
- 返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。
思路:
- 把字母记为1,数字记为-1,则题目要找的就是【最长和为0的子数组】
- 可以用前缀和来优化,找到前缀和【sumj-sumi==0】,更新最长长度 mx=j-i+1
- 我们用哈希表来记录上一个前缀和sumi出现的位置
- 如果哈希表中存在sumj,则更新最长长度mx
class Solution {
public String[] findLongestSubarray(String[] a) {
int s=0,n=a.length;
int mx=0,begin=0,end=0;
Map<Integer,Integer> mp=new HashMap<>();
mp.put(0,-1); //初始化
for(int i=0;i<n;i++)
{
s+= a[i].charAt(0)>='A'? 1:-1;
if(mp.containsKey(s))
{
int t=mp.get(s);
if(mx<i-t)
{
mx=i-t;
begin=t;
end=i;
}
}else mp.put(s,i);
}
String[] res=new String[mx];
return Arrays.copyOfRange(a,begin+1,end+1); //begin刚开始是-1 所以要+1
}
}