leetcode.面试题 17.05. 字母与数字 - 前缀和 + 哈希表

面试题 17.05. 字母与数字

题目:

  • 给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同
  • 返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。

思路:

  • 把字母记为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
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值