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

Kimi LeetCode 3333. 找到初始输入字符串 II Python3实现

LeetCode 3333. 找到初始输入字符串 II — Python3 实现

参考 doocs/leetcode 官方题解 ,提供两种 Python3 实现方案:

---

方法一:动态规划 + 前缀和(推荐)

```python
from typing import List
from itertools import accumulate

class Solution:
def possibleStringCount(self, word: str, k: int) -> int:
mod = 10**9 + 7
nums = [] # 每组可额外选择的字符数
ans = 1 # 总方案数(无长度限制)
cur = 0 # 当前组长度

for i, c in enumerate(word):
cur += 1
# 遇到组边界
if i == len(word) - 1 or c != word[i + 1]:
if cur > 1:
if k > 0:
nums.append(cur - 1) # 可额外删除 cur-1 个
ans = ans * cur % mod # 该组有 cur 种选择
cur = 0
k -= 1 # 每组至少选一个,k 减少

# 如果 k <= 0,说明每组至少选一个已经满足长度要求
if k < 1:
return ans

m = len(nums)
# f[i][j] 表示前 i 组中,额外选择 j 个字符的方案数
f = [[0] * k for _ in range(m + 1)]
f[0][0] = 1

for i, x in enumerate(nums, 1):
# 前缀和:s[j] = sum(f[i-1][0..j-1])
s = list(accumulate(f[i - 1], initial=0))
for j in range(k):
# f[i][j] = sum(f[i-1][j-x] ... f[i-1][j])
# 用前缀和优化:s[j+1] - s[max(0, j-x)]
l = max(0, j - x)
f[i][j] = (s[j + 1] - s[l] + mod) % mod

# 计算长度小于 k 的方案数(额外选择少于 k 个字符)
invalid = sum(f[m][j] for j in range(k)) % mod

# 答案 = 总方案数 - 长度小于 k 的方案数
return (ans - invalid) % mod
```

---

方法二:滑动窗口优化(空间优化至 O(k))

```python
from typing import List
from collections import deque

class Solution:
def possibleStringCount(self, word: str, k: int) -> int:
mod = 10**9 + 7

# 获取连续相同字符的分组长度
def get_groups(s: str) -> List[int]:
groups = []
cnt = 1
for i in range(1, len(s)):
if s[i] == s[i - 1]:
cnt += 1
else:
groups.append(cnt)
cnt = 1
groups.append(cnt)
return groups

groups = get_groups(word)

# 总方案数(无长度限制):每组长度相乘
total = 1
for g in groups:
total = total * g % mod

# 如果组数 >= k,任何字符串长度都至少为 k
if k <= len(groups):
return total

# 需要额外选择的字符数
need = k - len(groups)

# dp[j] 表示使用已处理组,额外选择 j 个字符的方案数
dp = [0] * need
dp[0] = 1 # 基础情况

for g in groups:
new_dp = [0] * need
window_sum = 0
# 滑动窗口:窗口大小为 g(该组可额外选择的字符数)
for j in range(need):
new_dp[j] = window_sum
window_sum = (window_sum + dp[j]) % mod
# 维护窗口大小
if j >= g - 1:
window_sum = (window_sum - dp[j - (g - 1)] + mod) % mod

dp = new_dp

# 计算无效方案数(长度小于 k)
invalid = sum(dp) % mod

return (total - invalid) % mod
```

---

核心思路

1. 分组统计:将连续相同字符分组,例如 `"aabbccdd"` → `[2,2,2,2]`。每组至少保留 1 个字符,可额外保留 0 到 `group-1` 个。

2. 总方案数:无长度限制时,每组有 `group` 种选择(保留 1 到 group 个),总方案数为各组长度乘积。

3. 长度约束:要求最终字符串长度 ≥ k。
- 先每组至少选 1 个,消耗 `groups.size()` 个字符。
- 剩余需要 `k - groups.size()` 个额外字符。
- 用 DP 计算额外选择少于 `k - groups.size()` 个字符的方案数,从总数中减去。

4. DP 优化:
- 前缀和:`f[i][j] = sum(f[i-1][j-x] ... f[i-1][j])`,用前缀和 O(1) 计算区间和。
- 滑动窗口:维护大小为 `group` 的窗口,空间优化至 O(k)。

复杂度分析

方法 时间复杂度 空间复杂度
前缀和 DP O(n + m×k) O(m×k)
滑动窗口 DP O(n + m×k) O(k)

其中 `m` 为分组数(`m ≤ n`),`k ≤ 2000`。两种方法均可通过,滑动窗口版本空间更优。

http://www.gsyq.cn/news/1564899.html

相关文章:

  • 构建标准化森林激光雷达数据集:多平台协同与算法评测基准
  • Mem Reduct终极指南:高效解决Windows内存卡顿的完整方案
  • 【架构实战】电商秒杀架构:高并发场景的终极挑战
  • MC68HC908QY4开发指南:MON08接口与低成本在线调试实战
  • 3步解锁你的QQ音乐:qmcdump让加密音乐重获自由播放权
  • AI论文软件推荐
  • 如何快速解锁小爱音箱:免费音乐播放的完整指南
  • 2026伟业铝材综合实力榜 价格透明,口碑实测不踩坑 - myqiye
  • emWin GUI开发实战:从控件、对话框到皮肤定制的嵌入式界面设计指南
  • AI学习搭子:3步把AI响应转化为真实知识神经元
  • 3个关键步骤:用智能拦截技术彻底解决机械键盘连击问题
  • 嵌入式GUI显示驱动配置实战:从emWin原理到硬件接口调试
  • 3分钟学会本地视频字幕提取:完全免费的AI工具终极指南
  • Trae多模型中转API配置实战:Claude/GPT-5.4/DeepSeek统一调度
  • 2026北京播音主持艺考培训机构实力盘点:聚焦班型配置与师资合规性 - 互联网科技品牌测评
  • 嵌入式GUI开发实战:emWin DROPDOWN与EDIT控件高级应用指南
  • 5分钟掌握VideoDownloadHelper:免费视频下载插件的完整使用教程
  • E-Hentai下载器完全指南:5分钟学会漫画批量下载
  • 2026年资质齐全的闪蒸干燥机定制品牌商实力公司推荐 - myqiye
  • 衣物洗护推荐:2026年6月这些品牌不容错过,专业衣物洗护/干洗工装洗涤/工装洗涤/鞋服清洗加工,衣物洗护公司哪家好 - 品牌推荐师
  • M365 Copilot配置三要素:感知、决策、执行层实操指南
  • 2026泸州漏水检测维修本地口碑防水商家榜单:厨卫/阳台/屋面/地下室渗漏水维修,持证施工+明码实价,防水补漏公司TOP5推荐 - 即刻修防水
  • One API:大模型API统一网关与协议转换实战指南
  • NXP S32R274/372评估板硬件配置与调试实战指南
  • 2026泰安漏水检测维修本地口碑防水商家榜单:厨卫/阳台/屋面/地下室渗漏水维修,持证施工+明码实价,防水补漏公司TOP5推荐 - 即刻修防水
  • 嵌入式音频系统设计:SCF5250芯片架构、解码优化与工程实践
  • Gemini Enterprise 3.0 pro零基础AI开发实战指南
  • 张量网络:机器学习高维数据处理与模型压缩新范式
  • 【Python工程化实战】Python 单体应用模块化设计:从面条代码到清晰边界
  • Gemini 3.1 Pro API接入实战:服务账号、Vertex AI与 Thinking Mode全解析