字节面试原题,两人都没做出来,都凉了

算法学习网址:wansuanfa.com (玩算法的拼音)

这题是LeetCode的第525题:连续数组。有两位网友在字节的面试中都遇到这题,不过很遗憾的是他俩都没做出来,至于后来有没有被录取就不知道了。这道题是一道中等难度的题,按说不算太难,下面我们就来看下。

f8c743f3a5ab252857043c4cf2ca2861.png

问题描述

来源:LeetCode第525题

难度:中等

给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。

示例1:

输入: nums = [0,1]

输出: 2

说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。

示例2:

输入: nums = [0,1,0]

输出: 2

说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。

  • 1 <= nums.length <= 10^5

  • nums[i] 不是 0 就是 1

问题分析

这题实际上是让求一个最长的子数组,并且这个子数组中0和1的数量必须相同。因为数组中的元素只能是0或1,直接计算不太好解,我们可以换种思路,把数组中的0换成-1。

这样0和1的数量必须相同就变成了-1和1的数量必须相同了,他们相加肯定是0,所以这题就变成了求一个最长的子数组,并且这个子数组的和必须是0。

我们以示例2为例来看下,改变之后的数组就变成了[-1,1,-1]。那么这题的解题思路就很明确了,我们可以直接使用前缀和,对改变之后的数组进行累加,然后使用一个map对累加的值进行存储,因为是求最大长度,如果遇到相同的值则不能覆盖。

关于前缀和的知识以及求最大长度,最小长度还有求频率的总结,大家可以参考我书中《算法秘籍》的10.3.3节,这里就不在过多介绍。

累加的时候如果出现相同的值,只需要用当前值的下标减去前面相同值的下标,中间这段就是和为0的子数组,我们只需要保存他的长度,记录最大值即可。

d8a03987de265960ff261a70627f190c.png

这里还要注意使用map存储前缀和的时候,要考虑0的情况,也就是说如果从数组的第一个元素到当前元素nums[i]的和是0,那么这个长度就是i+1,因为数组的下标是从0开始的,所以这里前缀和为0的时候,我们给它一个默认值-1。

JAVA:

public int findMaxLength(int[] nums) {
    Map<Integer, Integer> map = new HashMap<>();
    map.put(0, -1);// 前缀和为0的时候,给一个默认值-1。
    int preSum = 0, max = 0;
    for (int i = 0; i < nums.length; i++) {
        // 计算前缀和,原数组中如果是0,就让它变成-1。
        preSum += nums[i] == 0 ? -1 : 1;
        if (map.containsKey(preSum)) {
            // 如果出现相同的前缀和,就计算长度,并保存最大值。
            max = Math.max(max, i - map.get(preSum));
        } else {
            // 如果没有出现相同的前缀和,就把它存起来。
            map.put(preSum, i);
        }
    }
    return max;
}

C++:

public:
    int findMaxLength(vector<int>& nums) {
        unordered_map<int, int> mp ;
        mp[0]= -1;// 前缀和为0的时候,给一个默认值-1。
        int preSum = 0, maxLength = 0;
        for (int i = 0; i < nums.size(); i++) {
            // 计算前缀和,原数组中如果是0,就让它变成-1。
            preSum += nums[i] == 0 ? -1 : 1;
            if (mp.count(preSum)) {
                // 如果出现相同的前缀和,就计算长度,并保存最大值。
                maxLength = max(maxLength, i - mp[preSum]);
            } else {
                // 如果没有出现相同的前缀和,就把它存起来。
                mp[preSum]= i;
            }
        }
        return maxLength;
    }

-------------------------end-------------------------

笔者简介

博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解700多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据结构和算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值