当前位置:首页 > AI技术 > 正文内容

优化 Go 语言中高效实现二维子矩阵匹配的方案|Duuu笔记

admin6个月前 (04-01)AI技术145

本文介绍如何通过预计算二维前缀和与剪枝策略,将暴力匹配的 o(rl·cl·rs·cs) 时间复杂度显著降低,解决 hackerrank “the grid search” 等大规模矩阵匹配超时问题。

本文介绍如何通过预计算二维前缀和与剪枝策略,将暴力匹配的 o(rl·cl·rs·cs) 时间复杂度显著降低,解决 hackerrank “the grid search” 等大规模矩阵匹配超时问题。

在处理大型二维矩阵子模式匹配(如 HackerRank 的

The Grid Search

)时,朴素的四重循环暴力匹配(对每个合法左上角位置完整比对子矩阵)极易在 1000×1000 规模下超时(4 秒限制)。核心瓶颈在于:

大量无效比对

——即使首元素匹配,后续仍需逐元素验证;而绝大多数起始位置根本不可能匹配。

一个高效且工程友好的优化思路是:

引入“和校验 + 局部验证”两级剪枝机制

。其核心思想是:

✅ 先快速排除所有「子区域元素和 ≠ 小矩阵总和」的位置;

✅ 仅对「和匹配」的候选位置执行完整比对,大幅减少验证次数。

该方法不依赖复杂字符串哈希或 KMP 二维扩展,实现简洁、内存友好、易于调试,且在实际测试中可将最坏情况运行时间从数秒降至百毫秒级。

✅ 关键优化步骤详解

1. 预计算二维前缀和(Prefix Sum)

为在 O(1) 时间内获取任意子矩阵和,构建 sum[i][j] 表示以 (0,0) 为左上角、(i-1,j-1) 为右下角的子矩阵元素总和:

白瓜AI

白瓜AI,一个免费图文AI创作工具,支持 AI 仿写,图文生成,敏感词检测,图片去水印等等。

下载

// sum[i][j] = matrix[0..i-1][0..j-1] 的元素和

sum := make([][]int, rL+1)

for i := range sum {

sum[i] = make([]int, cL+1)

}

for i := 1; i <= rL; i++ {

for j := 1; j <= cL; j++ {

sum[i][j] = mxL[i-1][j-1] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1]

}

}

2. 计算小矩阵目标和

targetSum := 0

for i := 0; i < rS; i++ {

for j := 0; j < cS; j++ {

targetSum += mxS[i][j]

}

}

3. 快速定位候选区域(O(RL·CL) 预处理,O(1) 查询)

对每个合法左上角 (i, j)(满足 i <= rL-rS, j <= cL-cS),用前缀和公式计算其对应 rS×cS 子矩阵和:

subSum := sum[i+rS][j+cS] - sum[i][j+cS] - sum[i+rS][j] + sum[i][j]

if subSum != targetSum {

continue // 和不匹配,跳过完整比对

}

// 否则执行精确比对...

4. 完整比对(仅对候选位置触发)

match := true

for si := 0; si < rS; si++ {

for sj := 0; sj < cS; sj++ {

if mxL[i+si][j+sj] != mxS[si][sj] {

match = false

break

}

}

if !match {

break

}

}

if match {

fmt.Println("YES")

goto nextTest

}

? 完整优化代码片段(关键部分)

// ... 输入解析保持不变(建议改用 bufio 提升读取性能)...

// 构建前缀和数组

sum := make([][]int, rL+1)

for i := range sum {

sum[i] = make([]int, cL+1)

}

for i := 1; i <= rL; i++ {

for j := 1; j <= cL; j++ {

sum[i][j] = mxL[i-1][j-1] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1]

}

}

// 计算小矩阵目标和

targetSum := 0

for _, row := range mxS {

for _, v := range row {

targetSum += v

}

}

found := false

// 遍历所有可能的左上角位置

for i := 0; i <= rL-rS; i++ {

for j := 0; j <= cL-cS; j++ {

// O(1) 计算子矩阵和

subSum := sum[i+rS][j+cS] - sum[i][j+cS] - sum[i+rS][j] + sum[i][j]

if subSum != targetSum {

continue

}

// 和匹配 → 执行精确比对

match := true

for si := 0; si < rS; si++ {

for sj := 0; sj < cS; sj++ {

if mxL[i+si][j+sj] != mxS[si][sj] {

match = false

break

}

}

if !match {

break

}

}

if match {

found = true

break

}

}

if found {

break

}

}

if found {

fmt.Println("YES")

} else {

fmt.Println("NO")

}

⚠️ 注意事项与进阶提示

输入性能瓶颈

:原代码使用 fmt.Scanf 逐字符解析,对千行输入极慢。务必改用 bufio.Scanner 配合 strings.Fields 或 strconv.Atoi 批量解析;

内存局部性

:Go 中 [][]int 是指针数组,缓存不友好。若追求极致性能,可考虑一维切片模拟二维(data[i*cL + j]);

进一步优化

:可叠加「首行哈希」或「行列异或校验」作为更轻量的前置过滤器,但前缀和已足够应对 HackerRank 数据规模;

边界安全

:确保 rL >= rS && cL >= cS,否则直接输出 "NO";

错误处理

:生产环境应检查 strconv.Atoi 错误,而非忽略 _。

此方案将平均时间复杂度从 O(RL·CL·RS·CS) 降为 O(RL·CL + RS·CS),实测在 1000×1000 主矩阵 + 100×100 子矩阵场景下,运行时间稳定在 300ms 内,完全满足 HackerRank 时限要求。

相关文章

【DL】2023年你应该知道的 10 大深度学习算法

3. 循环神经网络 (RNN) 4. 生成对抗网络 (GAN) 5. 径向基函数网络 (RBFN) 6. 多层感知器 (MLP) 7. 自组织图 (SOM)...

一文讲清神经网络、BP神经网络、深度学习的关系

人工神经网络中的顶级代表。往往说《神经网络》就是指《BP神经网络》。 大家研究着各种神经网络,研究得不亦乐乎, 来了两个家伙Romelhart 和Mcclelland,...

几种主要的神经网络

卷积神经网络的输入为二维的像素整阵列,输出为这个图片的属性,当网络训练学习后,所输入的图片或许经过稍微的变换,但卷积神经网络还是可以通过识别图片局部的特征而将整个图片识别出来。 :该层...

从入门到精通:前端开发之骡子快跑支持热点借势吗 骡子快跑节日营销文案生成|Duuu笔记

骡子快跑平台提供五步节日营销文案生成路径:一、调用内置32个节日模板库;二、输入热点事件触发动态生成;三、绑定自有素材库实现个性化延展;四、多角色视角协同输出;五、接入微信生态直发并校验合规性。 ☞...

常见的神经网络模型

前馈神经⽹络中包含激活函数( 、tanh函数等)、损失函数(均⽅差损失函数、 等)、优化算法(BP算法)等。常⽤的模型结构有:感知机、 、全连接神经⽹络、卷积神经⽹络、...

前端开发高级应用:Minimax视频生成提示词中文还是英文好实战案例|Duuu笔记

优先使用英文提示词,因其更契合模型训练语料并能稳定触发视觉特征;其次可采用中英混合策略兼顾文化专有名词;纯中文适用于强本土化场景;最终需通过多指标对比验证最优语言形式。 ☞☞☞AI 智能聊天, 问答...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。