高效解决 LeetCode 2270: 分割数组的方案数

高效解决 LeetCode 2270: 分割数组的方案数

题目概述

题目编号 : 2270
题目名称 : 分割数组的方案数
难度: 中等

题目描述

给你一个下标从 0 开始、长度为 n 的整数数组 nums 。如果满足以下条件,则数组在下标 i 处有一个 合法的分割

  • i + 1 个元素的和 大于等于 剩下的 n - i - 1 个元素的和。
  • 下标 i 的右边至少有一个元素,即 0 <= i < n - 1

请你返回 nums合法分割方案数

示例

示例 1
复制代码
输入: nums = [10,4,-8,7]
输出: 2
解释:
- 在下标 0 处分割: [10] 和 [4,-8,7],10 >= 3 → 合法
- 在下标 1 处分割: [10,4] 和 [-8,7],14 >= -1 → 合法
- 在下标 2 处分割: [10,4,-8] 和 [7],6 < 7 → 不合法
总共合法的分割方案数为 2。
示例 2
复制代码
输入: nums = [2,3,1,0]
输出: 2
解释:
- 在下标 1 处分割: [2,3] 和 [1,0],5 >= 1 → 合法
- 在下标 2 处分割: [2,3,1] 和 [0],6 >= 0 → 合法
总共合法的分割方案数为 2。

解题思路

为了高效地解决这个问题,我们需要:

  1. 计算数组的总和,以便快速获取后半部分的和。
  2. 计算前缀和,即数组中每个位置前的所有元素的累计和。
  3. 遍历前缀和,并判断在每个可能的分割点,前半部分的和是否大于等于后半部分的和。
  4. 统计合法的分割点数

使用 Python 的 itertools.accumulate 函数可以高效地计算前缀和,从而优化我们的解决方案。

详细解答

关键函数解析

在提供的代码中,关键的部分是 accumulate(nums[:-1])。让我们逐步解析这一部分:

python 复制代码
from itertools import accumulate
from typing import List

class Solution:
    def waysToSplitArray(self, nums: List[int]) -> int:
        t = (sum(nums) + 1) // 2
        return sum(s >= t for s in accumulate(nums[:-1]))
1. 计算目标值 t
python 复制代码
t = (sum(nums) + 1) // 2
  • sum(nums) 计算整个数组的总和。
  • (sum(nums) + 1) // 2 计算的是总和的一半向上取整。这是为了确保在总和为奇数时,分割点的判断不受精度影响。
2. 计算前缀和
python 复制代码
accumulate(nums[:-1])
  • nums[:-1] 对原数组 nums 进行切片,去掉最后一个元素。这是因为分割点必须在 0 <= i < n - 1,即右侧至少有一个元素。
  • accumulate 函数生成一个前缀和的迭代器。例如,nums = [10, 4, -8, 7],则 accumulate(nums[:-1]) 生成的前缀和序列为 [10, 14, 6]
3. 统计合法分割点
python 复制代码
return sum(s >= t for s in accumulate(nums[:-1]))
  • 遍历前缀和序列,对于每个前缀和 s,判断 s >= t 是否成立。
  • 使用生成器表达式生成布尔值序列,True 代表合法的分割点。
  • sum 函数将 True 视为 1False 视为 0,最终统计出所有合法分割点的数量。

完整代码实现

python 复制代码
from itertools import accumulate
from typing import List

class Solution:
    def waysToSplitArray(self, nums: List[int]) -> int:
        # 计算数组的总和
        total_sum = sum(nums)
        # 计算目标值 t
        t = (total_sum + 1) // 2
        # 计算前缀和并统计满足条件的分割点
        return sum(s >= t for s in accumulate(nums[:-1]))

示例解析

示例 1 为例:

python 复制代码
nums = [10, 4, -8, 7]
  1. 计算总和 :

    复制代码
    sum(nums) = 10 + 4 + (-8) + 7 = 13
    t = (13 + 1) // 2 = 7
  2. 计算前缀和 :

    复制代码
    accumulate(nums[:-1]) = accumulate([10, 4, -8]) = [10, 14, 6]
  3. 判断每个前缀和是否大于等于 t :

    • 10 >= 7 → True
    • 14 >= 7 → True
    • 6 >= 7 → False
  4. 统计合法分割点数 :

    复制代码
    sum([True, True, False]) = 2

因此,返回结果为 2,即有两个合法的分割点。

总结

通过利用 Python 的 itertools.accumulate 函数,我们可以高效地计算前缀和,从而在 O(n) 的时间复杂度内解决 LeetCode 第2270题------分割数组的方案数。这种方法不仅简洁,而且在处理大规模数据时表现出色,是应对类似问题的理想选择。

希望本文能帮助你更好地理解这一问题的解决方案,并在实际编程中灵活运用前缀和的技巧。

参考资料

标签

  • Python
  • 算法
  • 前缀和
  • 编程技巧
  • LeetCode

版权声明

本文内容原创,转载请注明出处。

相关推荐
向阳而生,一路生花1 分钟前
深入浅出 JDK7 HashMap 源码分析
算法·哈希算法
君义_noip25 分钟前
信息学奥赛一本通 4150:【GESP2509七级】⾦币收集 | 洛谷 P14078 [GESP202509 七级] 金币收集
c++·算法·gesp·信息学奥赛·csp-s
摸个小yu34 分钟前
【力扣LeetCode热题h100】链表、二叉树
算法·leetcode·链表
汀、人工智能40 分钟前
[特殊字符] 第93课:太平洋大西洋水流问题
数据结构·算法·数据库架构·图论·bfs·太平洋大西洋水流问题
ZPC82101 小时前
rviz2 仿真控制器与真实机器人切换
人工智能·算法·机器人
澈2071 小时前
双指针,数组去重
c++·算法
小辉同志1 小时前
207. 课程表
c++·算法·力扣·图论
CheerWWW1 小时前
深入理解计算机系统——位运算、树状数组
笔记·学习·算法·计算机系统
仟濹2 小时前
2026-04-09~10-复习计划+蓝桥杯注意的点
职场和发展·蓝桥杯
锅挤2 小时前
数据结构复习(第一章):绪论
数据结构·算法