高效解决 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

版权声明

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

相关推荐
江畔柳前堤13 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore14 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考16 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX17 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面17 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号17 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽18 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI18 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者19 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者19 小时前
【征程6】校准量化中HistogramObserver解析
算法