给定一个整数数组 nums 和一个整数 m,初始时整个数组是一个连续子数组。每次操作可以选择当前长度大于 1 的连续子数组,并将其拆分成两个非空的连续子数组。一个子数组被认为是合法的,当且仅当它的长度等于 1,或者该子数组中所有元素的总和大于等于 m。要求判断是否可以通过一系列拆分操作,最终将整个数组拆分成长度全部为 1 的单元素子数组。如果可以完成完整拆分,则返回 true,否则返回 false。
示例 1:
输入:
nums = [2, 2, 1]
m = 4
输出:
true
解释:
[2, 2, 1]。[2, 2] 和 [1]。[1] 的长度为 1,因此天然合法。[2, 2] 的元素和为 4,满足 sum >= m,因此可以继续拆分。[2, 2] 拆分成两个单元素数组,因此整个数组可以完成拆分。示例 2:
输入:
nums = [2, 1, 3]
m = 5
输出:
false
解释:
[2, 1] 和 [3],则 [2, 1] 的元素和为 3,小于 m = 5,无法继续拆分。[2] 和 [1, 3],则 [1, 3] 的元素和为 4,同样小于 m = 5,无法继续拆分。示例 3:
输入:
nums = [1, 2, 3, 4]
m = 5
输出:
true
解释:
2 和 3,其和为 5,满足 sum >= m。2 的子数组。1 的子数组一定是长度为 2 的子数组,因为下一步必须把它拆成两个长度为 1 的子数组。m。1 的子数组天然合法。2 的连续子数组拆成两个单元素数组。2 的子数组必须满足两个元素之和大于等于 m。i,满足 nums[i] + nums[i + 1] >= m。nums 的长度。len(nums) <= 2,直接返回 true。i,计算 nums[i] + nums[i + 1]。m,立即返回 true。false。1 的数组不需要进行拆分,因此直接返回 true。2 的数组可以直接拆成两个单元素数组,因此直接返回 true。m,仍然满足要求。10^7 甚至更大,可以使用流式处理,只维护前一个元素和当前元素。m,即可立即停止读取并返回 true。len(nums) <= 2 或者前两个元素已经满足条件。class Solution:
def canSplitArray(self, nums: list[int], m: int) -> bool:
# 长度为 1 时,数组已经是最终状态,不需要执行任何拆分操作。
# 长度为 2 时,可以直接拆成两个长度为 1 的子数组,因此同样一定可以完成拆分。
if len(nums) <= 2:
return True
# 最后一次合法拆分一定发生在一个长度为 2 的子数组上。
# 因此我们只需要寻找一对相邻元素,使它们的和至少为 m。
for i in range(len(nums) - 1):
# 当前检查 nums[i] 和 nums[i + 1] 这两个相邻元素。
# 如果它们的和达到 m,这一对元素就可以作为整个拆分过程的最后一步。
if nums[i] + nums[i + 1] >= m:
# 找到满足条件的相邻元素对后,
# 可以构造出完整的合法拆分过程,因此立即返回 True。
return True
# 所有相邻元素对都不满足条件,
# 说明不存在可以完成最后一次拆分的长度为 2 的子数组。
return False掌握同类考点的变体套路与最优解模板,举一反三快速拿下技术面试: