深入研究:回文和连续块的递归解决方案
本篇文章向大家介绍《深入研究:回文和连续块的递归解决方案》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。

在本文中,我们将解决 perl weekly challenge #288 中的两项任务:找到最接近的回文并确定矩阵中最大连续块的大小。这两种解决方案都将在 perl 和 go 中递归实现。
目录
- 最近的回文
- 连续块
- 结论
最近的回文
第一个任务是找到最接近的不包含自身的回文。
最接近的回文被定义为最小化两个整数之间的绝对差的回文。
如果有多个候选者,则应返回最小的一个。
任务描述
输入: 字符串 $str,代表整数。
输出: 最接近的回文字符串。
示例
输入:“123”
输出:“121”输入: "2"
输出:“1”
有两个最接近的回文:“1”和“3”。因此,我们返回最小的“1”。输入:“1400”
输出:“1441”输入:“1001”
输出:“999”
解决方案
perl 实现
在此实现中,我们利用递归方法来查找不等于原始数字的最接近的回文。递归函数探索原始数字的下限和上限:
- 它检查当前候选(下级和上级)是否是有效的回文(并且不等于原始)。
- 如果两个候选都无效,该函数会递归地递减较低的候选并递增较高的候选,直到找到有效的回文。
这种递归策略有效地缩小了搜索空间,确保我们在遵守问题约束的同时识别最接近的回文。
sub is_palindrome {
my ($num) = @_;
return $num eq reverse($num);
}
sub find_closest {
my ($lower, $upper, $original) = @_;
return $lower if is_palindrome($lower) && $lower != $original;
return $upper if is_palindrome($upper) && $upper != $original;
return find_closest($lower - 1, $upper + 1, $original) if $lower > 0;
return $upper + 1;
}
sub closest_palindrome {
my ($str) = @_;
my $num = int($str);
return find_closest($num - 1, $num + 1, $num);
}
实施
go 实现遵循类似的递归策略。它还检查原始数字周围的候选数,使用递归来调整边界,直到找到有效的回文数。
package main
import (
"strconv"
)
func ispalindrome(num int) bool {
reversed := 0
original := num
for num > 0 {
digit := num % 10
reversed = reversed*10 + digit
num /= 10
}
return original == reversed
}
func findclosest(lower, upper, original int) string {
switch {
case ispalindrome(lower) && lower != original:
return strconv.itoa(lower)
case ispalindrome(upper) && upper != original:
return strconv.itoa(upper)
case lower > 0:
return findclosest(lower-1, upper+1, original)
default:
return strconv.itoa(upper + 1)
}
}
func closestpalindrome(str string) string {
num, _ := strconv.atoi(str)
return findclosest(num-1, num+1, num)
}
hier ist die erweiterte definition für den 连续块:
连续块
第二个任务是确定给定矩阵中最大连续块的大小,其中所有单元格都包含 x 或 o。
连续块由包含相同符号的元素组成,这些元素与块中的其他元素共享边缘(而不仅仅是角),从而创建一个连接区域。
任务描述
输入: 包含 x 和 o 的矩形矩阵。
输出:最大连续块的大小。
示例
-
输入:
[ ['x', 'x', 'x', 'x', 'o'], ['x', 'o', 'o', 'o', 'o'], ['x', 'o', 'o', 'o', 'o'], ['x', 'x', 'x', 'o', 'o'], ]
输出: 11
有一个包含 x 的 9 个连续单元格的块和一个包含 o 的 11 个连续单元格的块。
-
输入:
[ ['x', 'x', 'x', 'x', 'x'], ['x', 'o', 'o', 'o', 'o'], ['x', 'x', 'x', 'x', 'o'], ['x', 'o', 'o', 'o', 'o'], ]
输出: 11
有一个包含 x 的 11 个连续单元格的块和一个包含 o 的 9 个连续单元格的块。
-
输入:
[ ['x', 'x', 'x', 'o', 'o'], ['o', 'o', 'o', 'x', 'x'], ['o', 'x', 'x', 'o', 'o'], ['o', 'o', 'o', 'x', 'x'], ]
输出: 7
有一个包含 o 的 7 个连续单元格块、另外两个包含 o 的 2 单元格块、三个包含 x 的 2 单元格块和一个包含 x 的 3 单元格块。
解决方案
perl 实现
在此实现中,我们利用递归深度优先搜索(dfs)方法来确定矩阵中最大连续块的大小。主函数初始化一个访问矩阵来跟踪哪些单元已被探索。它迭代每个单元格,每当遇到未访问的单元格时调用递归 dfs 函数。
dfs 函数探索当前单元格的所有四个可能的方向(上、下、左、右)。它通过在共享相同符号且尚未被访问的相邻单元上递归地调用自身来计算连续块的大小。这种递归方法有效地聚合了块的大小,同时确保每个单元仅被计数一次。
sub largest_contiguous_block {
my ($matrix) = @_;
my $rows = @$matrix;
my $cols = @{$matrix->[0]};
my @visited = map { [(0) x $cols] } 1..$rows;
my $max_size = 0;
for my $r (0 .. $rows - 1) {
for my $c (0 .. $cols - 1) {
my $symbol = $matrix->[$r][$c];
my $size = dfs($matrix, \@visited, $r, $c, $symbol);
$max_size = $size if $size > $max_size;
}
}
return $max_size;
}
sub dfs {
my ($matrix, $visited, $row, $col, $symbol) = @_;
return 0 if $row < 0 || $row >= @$matrix || $col < 0 || $col >= @{$matrix->[0]}
|| $visited->[$row][$col] || $matrix->[$row][$col] ne $symbol;
$visited->[$row][$col] = 1;
my $count = 1;
$count += dfs($matrix, $visited, $row + 1, $col, $symbol);
$count += dfs($matrix, $visited, $row - 1, $col, $symbol);
$count += dfs($matrix, $visited, $row, $col + 1, $symbol);
$count += dfs($matrix, $visited, $row, $col - 1, $symbol);
return $count;
}
实施
go 实现反映了这种递归 dfs 策略。它类似地遍历矩阵并使用递归来探索具有相同符号的连续单元格。
package main
func largestContiguousBlock(matrix [][]rune) int {
rows := len(matrix)
if rows == 0 {
return 0
}
cols := len(matrix[0])
visited := make([][]bool, rows)
for i := range visited {
visited[i] = make([]bool, cols)
}
maxSize := 0
for r := 0; r < rows; r++ {
for c := 0; c < cols; c++ {
symbol := matrix[r][c]
size := dfs(matrix, visited, r, c, symbol)
if size > maxSize {
maxSize = size
}
}
}
return maxSize
}
func dfs(matrix [][]rune, visited [][]bool, row, col int, symbol rune) int {
if row < 0 || row >= len(matrix) || col < 0 || col >= len(matrix[0]) ||
visited[row][col] || matrix[row][col] != symbol {
return 0
}
visited[row][col] = true
count := 1
count += dfs(matrix, visited, row+1, col, symbol)
count += dfs(matrix, visited, row-1, col, symbol)
count += dfs(matrix, visited, row, col+1, symbol)
count += dfs(matrix, visited, row, col-1, symbol)
return count
}
结论
在本文中,我们探讨了 perl weekly challenge #288 中的两个有趣的挑战:找到最接近的回文并确定矩阵中最大连续块的大小。
对于第一个任务,perl 和 go 实现都有效地利用递归来导航原始数字,确保有效地找到最接近的回文。
在第二个任务中,两种语言的递归深度优先搜索方法可以对矩阵进行彻底探索,从而准确计数最大连续的相同符号块。
这些挑战凸显了递归作为解决算法问题的强大工具的多功能性,展示了它在 perl 和 go 中的有效性。如果您有兴趣进一步探索或有任何疑问,请随时联系!
您可以在 github 上找到完整的代码,包括测试。
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。
监控和故障排除 Golang 函数与外部 API 交互
- 上一篇
- 监控和故障排除 Golang 函数与外部 API 交互
- 下一篇
- PHP 函数安全问题在生产环境中的解决之道
-
- Golang · Go教程 | 16分钟前 |
- Golang网络包丢失处理方法解析
- 469浏览 收藏
-
- Golang · Go教程 | 20分钟前 |
- Golang反射实现通用代理方法解析
- 402浏览 收藏
-
- Golang · Go教程 | 23分钟前 |
- Golang并发缓存实现与淘汰策略详解
- 406浏览 收藏
-
- Golang · Go教程 | 28分钟前 |
- Golang切片扩容原理与优化技巧
- 213浏览 收藏
-
- Golang · Go教程 | 29分钟前 |
- Golang模块版本选择与对比方法
- 457浏览 收藏
-
- Golang · Go教程 | 31分钟前 |
- Golang安全使用K8sSecret管理敏感数据
- 282浏览 收藏
-
- Golang · Go教程 | 41分钟前 |
- Golang生成二维码工具实战教程
- 454浏览 收藏
-
- Golang · Go教程 | 53分钟前 |
- Golang值类型优化与内存管理技巧
- 463浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3201次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3414次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3444次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4552次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3822次使用
-
- Golangmap实践及实现原理解析
- 2022-12-28 505浏览
-
- go和golang的区别解析:帮你选择合适的编程语言
- 2023-12-29 503浏览
-
- 试了下Golang实现try catch的方法
- 2022-12-27 502浏览
-
- 如何在go语言中实现高并发的服务器架构
- 2023-08-27 502浏览
-
- 提升工作效率的Go语言项目开发经验分享
- 2023-11-03 502浏览

