当前位置: 首页 > news >正文

Kimi k2.6 LeetCode 2972. 统计移除递增子数组的数目 II Python3实现

以下是 LeetCode 2972. 统计移除递增子数组的数目 II 的 Python3 实现,采用双指针思路。

核心思路

1. 找最长递增前缀:从左边开始找到最长的严格递增前缀,末尾索引为 `i`
2. 找最长递增后缀:从右边开始找到最长的严格递增后缀,起始索引为 `startIndex`
3. 双指针枚举:枚举左前缀的结束位置,用双指针找到右后缀中第一个大于左前缀末尾的位置,计算可移除的子数组数量

如果整个数组已经严格递增,则任意子数组都是移除递增的,答案为 `n * (n + 1) // 2`。

Python3 代码

```python
from bisect import bisect_right
from typing import List

class Solution:
def incremovableSubarrayCount(self, nums: List[int]) -> int:
n = len(nums)

# 找到最长递增前缀的末尾索引
i = 0
while i + 1 < n and nums[i] < nums[i + 1]:
i += 1

# 如果整个数组严格递增,任意子数组移除后都递增
if i == n - 1:
return n * (n + 1) // 2

# 找到最长递增后缀的起始索引
startIndex = n - 1
while startIndex > 0 and nums[startIndex - 1] < nums[startIndex]:
startIndex -= 1

# 情况1:移除子数组包含整个后缀 [startIndex..n-1]
# 左前缀可以是 [0..0], [0..1], ..., [0..i] 以及空(移除整个数组)
# 共 i + 2 种(空前缀 + i+1 种非空前缀)
ans = i + 2

# 双指针:枚举左前缀结束位置 j,找右后缀中第一个 > nums[j] 的位置
j = startIndex
for left_end in range(startIndex):
# 左前缀必须严格递增,遇到非递增则停止
if left_end > 0 and nums[left_end] <= nums[left_end - 1]:
break

# 移动右指针,找到第一个 > nums[left_end] 的位置
while j < n and nums[j] <= nums[left_end]:
j += 1

# 可移除的子数组为 [left_end+1 .. k],其中 k 从 j-1 到 n-1
# 即移除子数组的右端点可以是 j-1, j, ..., n-1
# 共 n - j + 1 种
ans += n - j + 1

return ans
```

另一种实现(更简洁的双指针)

```python
from typing import List

class Solution:
def incremovableSubarrayCount(self, nums: List[int]) -> int:
n = len(nums)

# 找最长递增前缀末尾
i = 0
while i + 1 < n and nums[i] < nums[i + 1]:
i += 1

# 整个数组递增
if i == n - 1:
return n * (n + 1) // 2

# 找最长递增后缀起点
startIndex = n - 1
while startIndex > 0 and nums[startIndex - 1] < nums[startIndex]:
startIndex -= 1

ans = 0
j = startIndex

# left_end 从 -1 开始(表示空前缀)
for left_end in range(-1, startIndex):
if left_end >= 0:
# 左前缀必须严格递增
if left_end > 0 and nums[left_end] <= nums[left_end - 1]:
break
# 移动右指针
while j < n and nums[j] <= nums[left_end]:
j += 1

# 可移除子数组数量
ans += n - j + 1

return ans
```

关键点说明

要点 说明
递增前缀 `nums[0..i]` 是最长的严格递增前缀
递增后缀 `nums[startIndex..n-1]` 是最长的严格递增后缀
双指针 `left_end` 枚举左前缀结束位置,`j` 指向右后缀中第一个 `> nums[left_end]` 的位置
可移除子数组 对于固定的 `left_end`,移除子数组可以是 `[left_end+1 .. k]`,其中 `k ∈ [j-1, n-1]`,共 `n-j+1` 种
边界条件 `left_end = -1` 表示空前缀,即只保留右后缀

复杂度分析

- 时间复杂度:O(n),双指针每个位置最多访问一次
- 空间复杂度:O(1)

http://www.jsqmd.com/news/951871/

相关文章:

  • SourceGit:让Git版本控制变得直观高效的跨平台图形化解决方案
  • 智慧教育平台电子课本一键解析:告别繁琐下载的智能解决方案
  • 新手福音:用快马平台生成练习项目,轻松理解github协作开发
  • 【会议征稿通知 | 中国教育发展战略学会教育大数据专业委员会主办 | SPIE出版 | EI 、Scopus稳定检索】第六届先进算法与信号、图像处理国际学术会议(AASIP 2026)
  • 别再怕约束了!手把手教你用QUBO模型把复杂优化问题‘拍扁’成无约束问题
  • 【深度解析】Gemma 4 12B:面向本地 Agent 工作流的统一多模态模型与 OpenAI 兼容接入实践
  • ContextMenuForWindows11开源项目:彻底解放你的右键菜单生产力
  • 如何快速构建你的专属离线英语发音库:11万单词MP3音频一键下载指南
  • LabVIEW 2019生成DLL实战:手把手教你用C# WinForm调用(附避坑指南)
  • 如何永久保存微信聊天记录:掌握你的数字记忆主权
  • 豆包收费成字节AI转折点:顾全全离职,AI4S团队何去何从?
  • 别再乱改my.cnf了!MySQL 8.0+Docker大小写敏感问题的根治方案
  • iFakeLocation终极指南:三步完成iOS虚拟定位的完整方案
  • 2026年近期潍坊行业知名的智能热水龙头生产商怎么选择?专业解析与推荐 - 2026年企业资讯
  • 当H.265遇见老协议:一次给FFmpeg‘打补丁’,让旧直播架构兼容HEVC的实践记录
  • 昌平区如何选购靠谱的近视防控眼镜? - mypinpai
  • 解锁AI绘画的魔法钥匙:ComfyUI ControlNet Aux全功能探索指南
  • Webots仿真翻车实录:从‘球体自由落体’到‘小车原地打转’,我踩过的那些物理参数坑
  • 2026年特色美食分量足的景点排行榜,选购指南 - mypinpai
  • 5个关键步骤:用BG3ModManager轻松管理博德之门3模组
  • 今日开源[第7期]spec-kit - zhang
  • 效率提升:基于dezmall设计规范,用快马AI一键生成管理后台框架
  • 实时流式聚类×多模态AI工具链整合:单日处理2.4亿用户行为数据的低延迟架构(已通过等保三级认证)
  • 告别烂三角!用CGAL的isotropic_remeshing函数一键优化你的3D网格模型
  • 2026微信小程序商城平台深度解析:全链路选型与技术能力实测
  • 棕熊英语启蒙课程机构的性价比哪家高? - mypinpai
  • 如何用AI视觉技术彻底革新你的象棋学习体验:Vin象棋完整指南
  • 首尔国立大学的这项新技术让病理分析效率提升百倍
  • 5分钟掌握B站视频数据批量采集:告别手动统计的高效解决方案
  • hw八股准备