删掉一个元素以后全为1的最长子数组-LeetCode
🎯 问题描述(来源于LeetCode)
描述:给你一个二进制数组 nums,你可以在其中删除至多一个元素。请你返回删除一个元素后,数组中全为 1 的最长子数组的长度。
说明:如果数组全是 1,你必须删除一个,所以结果要减 1。
- 示例:
- 示例 1:
1
2
3输入: nums = [1,1,0,1]
输出: 3
解释: 删除下标 2 的 0,得到 [1,1,1]。 - 示例 2:
1
2
3输入: nums = [1,1,1]
输出: 2
解释: 必须删除一个 1,结果为 [1,1]。
- 示例 1:
💻 解题思路
思路:滑动窗口 (Sliding Window)
- 维护窗口:维护一个窗口,使其最多包含 1 个 0。
- 移动指针:
right指针遍历数组,将元素加入窗口。- 如果窗口内
0的数量超过 1,则移动left指针收缩窗口。
- 更新答案:在窗口合法时,利用
Counter直接获取窗口内1的数量更新最大值。 - 边界处理:如果最大长度等于数组长度,说明全是 1,必须减 1。
思路1:代码实现
1 | class Solution: |
思路1:📊 性能分析
- 时间复杂度:。每个元素最多被
right访问一次,被left访问一次。 - 空间复杂度:。
Counter最多存储两个键值对 (0 和 1),空间是常数级的。
思考
- 为什么现在
count[1]能用了?
核心在于count[nums[left]] -= 1。这行代码保证了count字典永远只记录当前窗口内的数据。此时count[1]就是窗口内 1 的真实数量。 - 两种写法的取舍:
虽然count[1]在逻辑上是通的,但在工程实践中,(right - left + 1) - count[0]通常更受青睐。因为计算(right - left + 1)是 的算术运算,而访问count[1]涉及哈希表查找(虽然极快,但理论上比加减法慢)。不过,在这道题中,两者的性能差异几乎可以忽略不计。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






