当前位置: 首页 > 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.jsqmd.com/news/1052984/

相关文章:

  • 基于emWin GUIDRV_Template与VNC的嵌入式GUI驱动开发实战
  • 2026洛阳漏水检测维修本地口碑防水商家榜单:厨卫/阳台/屋面/地下室渗漏水维修,持证施工+明码实价,防水补漏公司TOP5推荐 - 即刻修防水
  • TMSpeech完整指南:5分钟掌握Windows本地实时语音转文字
  • 营养轻食交易平台系统
  • 构建标准化森林激光雷达数据集:多平台协同与算法评测基准
  • Mem Reduct终极指南:高效解决Windows内存卡顿的完整方案
  • 鲁棒最优实验设计:应对传感器失效的工程实践与算法实现
  • MC68HC908QY4开发指南:MON08接口与低成本在线调试实战
  • 喜来客值得信赖吗 十大用户真实评价与避坑要点 - myqiye
  • MinerU与LlamaIndex深度集成:实现文档语义结构对齐的RAG构建指南
  • 【架构实战】电商秒杀架构:高并发场景的终极挑战
  • AI论文软件推荐
  • 3步解锁你的QQ音乐:qmcdump让加密音乐重获自由播放权
  • AI决策优化:在容量约束与噪声依从下如何科学设定干预阈值
  • 第6章:Python接入Ollama——构建第一个AI小助手
  • 嵌入式GUI图像处理实战:BMP/JPEG/GIF格式选择与emWin API优化
  • 魔兽争霸3终极优化指南:三步免费解决宽屏适配、地图加载与帧率问题
  • 大湾区生物医药EMBA实测解析与科学选型指南
  • 嵌入式系统硬件开关配置详解:以QorIQ T1023启动与IFC接口为例
  • 如何快速解锁小爱音箱:免费音乐播放的完整指南
  • 基于LLM日志的零成本自适应路由系统TRACER设计与实践
  • 2026伟业铝材综合实力榜 价格透明,口碑实测不踩坑 - myqiye
  • ASC、GSC+与Δ-替代:从需求类型出发,系统化设计集合函数类的思维框架
  • 小程序安全通信机制深度解析:从签名算法到逆向分析实践
  • 3分钟学会本地视频字幕提取:完全免费的AI工具终极指南
  • 3个关键步骤:用智能拦截技术彻底解决机械键盘连击问题
  • AI学习搭子:3步把AI响应转化为真实知识神经元
  • Codex桌面版本地桥接DeepSeek V4实战指南
  • emWin GUI开发实战:从控件、对话框到皮肤定制的嵌入式界面设计指南
  • 嵌入式GUI显示驱动配置实战:从emWin原理到硬件接口调试