面试题 17.05. 字母与数字

面试题 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:前缀和+最左侧下标探测

public String[] findLongestSubarray(String[] array) {
    int n = array.length;
    int[] sum = new int[n];
    for (int i = 0; i < array.length; i++) {
        String s = array[i];
        //数字可能是 42 19 这样的
        if (s.compareTo("A") >= 0 && s.compareTo("z") <= 0) {
            sum[i] = -1;
        } else {
            sum[i] = 1;
        }
    }
    for (int i = 1; i < n; i++) sum[i] += sum[i - 1];
    int l = -1, r = -1;
    Map<Integer, Integer> map = new HashMap<>();//记录当前值的最左侧的下标
    for (int i = 0; i < n; i++) {
        if (sum[i] == 0) {//为0的情况
            if (r - l + 1 < i + 1) {
                r = i;
                l = 0;
            }
            continue;
        }
        //记录下第一次出现的数字的最左侧的下标
        if (!map.containsKey(sum[i])) map.put(sum[i], i);
        else {
            if (r - l + 1 < i - map.get(sum[i])) {
                r = i;
                l = map.get(sum[i]) + 1;
            }
        }
    }
    if (l == -1 && r == -1) return new String[]{};
    return Arrays.copyOfRange(array, l, r + 1);//取头不取尾
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值