news 2026/6/15 13:58:32

一次遍历+维护前后缀+枚举中间+位运算

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一次遍历+维护前后缀+枚举中间+位运算

lc2484

前缀、后缀数组分别统计数字对的出现次数,枚举字符串中间字符

累加前后缀相同数字对的乘积,得到长度为5的回文子序列总数。

class Solution {
const long MOD = 1e9 + 7;
public:
int countPalindromes(string s) {
int suf[10]{}, suf2[10][10]{}, pre[10]{}, pre2[10][10]{};
for (int i = s.length() - 1; i >= 0; --i) {
char d = s[i] - '0';
for (int j = 0; j < 10; ++j)
suf2[d][j] += suf[j];
++suf[d]; //预处理后缀
}

long ans = 0L;
for (char d : s) {
d -= '0';
--suf[d];
for (int j = 0; j < 10; ++j)
suf2[d][j] -= suf[j]; // 撤销


for (int j = 0; j < 10; ++j)
for (int k = 0; k < 10; ++k)
ans += (long) pre2[j][k] * suf2[j][k]; // 枚举所有字符组合


for (int j = 0; j < 10; ++j)
pre2[d][j] += pre[j];
++pre[d];

}
return ans % MOD;
}
};

lc1930

unordered_map<char, pair<int, int>> hash;算起止

class Solution {
public:
int countPalindromicSubsequence(string s)
{
int n = s.size();
unordered_map<char, pair<int, int>> hash;
for (int i = 0; i < n; ++i)
{
if (!hash.count(s[i]))
hash[s[i]].first = i;
hash[s[i]].second = i;
}
int ret = 0;
for (auto& [ch, pos] : hash) {
int first = pos.first;
int last = pos.second;
if (last - first < 2) continue; // 中间没有字符,无法形成长度为3的回文
unordered_set<char> st;
for (int i = first + 1; i < last; ++i)
st.insert(s[i]);
ret += st.size();
}
return ret;
}
};

优化

一次遍历+维护前后缀+枚举中间+位运算

前缀后缀二进制标记字符存在性

枚举字符串中间字符作为回文中心

has[mid] |= pre & suf;

累加得到长度为3的回文子序列总数

for (int mask : has)
ans += popcount((uint32_t) mask);

算法就是 一次遍历 不断维护

class Solution {
public:
int countPalindromicSubsequence(string s) {
int n = s.size();
// 统计 [1,n-1] 每个字母的个数
int suf_cnt[26]{};
int suf = 0;
for (int i = 1; i < n; i++) {
int ch = s[i] - 'a';
suf_cnt[ch]++;
suf |= 1 << ch; // 把 ch 记录到二进制数 suf 中,表示后缀有 ch
}

int pre = 0;
int has[26]{}; // has[mid] = 由 alpha 组成的二进制数
for (int i = 1; i < n - 1; i++) { // 枚举中间字母 mid
int mid = s[i] - 'a';
suf_cnt[mid]--;

// 撤销 mid 的计数,suf_cnt 剩下的就是后缀 [i+1,n-1] 每个字母的个数
if (suf_cnt[mid] == 0)

// 后缀 [i+1,n-1] 不包含 mid
suf ^= 1 << mid;

// 从 suf 中去掉 mid

pre |= 1 << (s[i - 1] - 'a');

// 把 s[i-1] 记录到二进制数 pre 中,表示前缀有 s[i-1]
has[mid] |= pre & suf;

// 计算 pre 和 suf 的交集,|= 表示把交集中的字母加到 has[mid] 中
}

int ans = 0;
for (int mask : has) {
ans += popcount((uint32_t) mask);

//每个字符 has一个的记录表

// mask 中的每个 1 对应着一个 alpha
}
return ans;
}
};

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 10:48:05

大模型面试题55:vLLM 调优方法

vLLM 是目前最快的开源 LLM 推理框架之一,核心靠 PagedAttention 机制(类比操作系统的“分页内存”)高效管理 KV Cache,大幅提升吞吐量、降低延迟。 调优的核心目标很简单:在有限显存下,跑更快、塞更多请求、出结果更稳。下面从小白能上手的「纯配置调参」,到需要一点技…

作者头像 李华
网站建设 2026/6/15 1:47:39

中文NER服务部署案例:RaNER模型在新闻摘要中的应用

中文NER服务部署案例&#xff1a;RaNER模型在新闻摘要中的应用 1. 引言&#xff1a;AI 智能实体侦测服务的业务价值 在信息爆炸的时代&#xff0c;新闻媒体、舆情监控、知识图谱构建等场景面临海量非结构化文本处理的挑战。如何从一篇篇新闻报道中快速提取关键人物、地点和机…

作者头像 李华
网站建设 2026/6/13 9:31:12

Linux SCP效率提升:告别手动输入,一键完成传输

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 设计一个效率工具&#xff0c;能够记录用户常用的SCP命令模板&#xff0c;支持一键调用和参数快速填充。工具应具备智能补全功能&#xff0c;根据历史记录和当前路径自动推荐命令参…

作者头像 李华
网站建设 2026/6/13 7:18:59

用SpringDoc快速验证API设计:原型开发新思路

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个Spring Boot项目原型&#xff0c;仅包含API接口定义但不需要实现业务逻辑。使用SpringDoc生成这些API的文档&#xff0c;并通过Swagger UI展示。要求&#xff1a;1) 定义5…

作者头像 李华
网站建设 2026/6/10 0:49:22

AI如何帮你快速生成城市道路规划代码

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个城市道路规划系统&#xff0c;根据输入的城市区域面积、人口密度和交通流量&#xff0c;自动生成优化的道路网络布局。要求包括&#xff1a;1. 主次干道分级设计 2. 交叉口…

作者头像 李华
网站建设 2026/6/8 3:57:00

VSCode + Claude:AI编程助手如何提升你的开发效率

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个VSCode插件&#xff0c;集成Claude AI助手功能。插件应支持&#xff1a;1) 通过自然语言描述生成代码片段&#xff1b;2) 解释复杂代码逻辑&#xff1b;3) 自动修复常见错…

作者头像 李华