有趣的算法(九) ——蛇形数组
有趣的算法(九)——蛇形数组
(原创内容,转载请注明来源,谢谢)
一、问题阐述
给定一个数字,需要返回的内容如下图所示:
输入5,得到结果:
输入10,得到结果:
输入一个数字i,输出结果的矩阵是i行i列的。矩阵从右上角开始,从1开始往下,每增加1行加1。到第i行后,再往左,每左一列加1。到头后再往上、往右、再往下....,其中已经填上的数字不能覆盖,直接转向。因为其生成的过程类似盘旋的蛇,故称为蛇形数组。
现要求输入任意元素i,返回矩阵内容。
二、问题分析
初看问题,看似很简单,用几个循环就可以解决问题。但是,当真正开始写循环的时候,就容易卡住。
对于此问题,用循环解决,需要考虑边界条件,以及如何进行循环。
1)如何进行循环
根据蛇形数组的生成过程,由左上方开始循环。共需要四类的循环,从左上到下、从下右到左、从左下到上、从上左到右,其中的上下左右都是相对的位置。
2)边界问题
循环何时退出,主要有两点:1是不能超过边界,输入的是i,则元素不能超出i;2是不能覆盖原有的内容,所以可以在对每个元素进行赋值的时候进行判断,如果已经有内容,则直接转向。
当触及边界问题,则按照第一点提到的四种循环,按顺序执行。
3)循环结束条件
上述的四个循环,只能完成一次的矩阵内容填充,故还需要一个总的循环。考虑到输入i,结果数组的元素个数是i*i,故循环结束的条件就是当值大于i*i,则结束循环。
三、实现
PHP实现过程如下:
function snakenumber($level){
$max = $level * $level;//最大数量
$count = 1;//初始值为1
//初始从左上方开始
$row = 0;
$column = $level - 1;
$res[$row][$column] = $count;
while($max > $count)
{
while($level > $row+1 && !isset($res[$row+1][$column]))$res[++$row][$column] = ++$count;//从右往下
while(0 <= $column-1 && !isset($res[$row][$column-1]))$res[$row][--$column] = ++$count;//从下往左
while(0 <= $row-1 && !isset($res[$row-1][$column]))$res[--$row][$column] = ++$count;//从左往上
while($level > $column+1 && !isset($res[$row][$column+1]))$res[$row][++$column] = ++$count;//从上往左
}
}
结果如问题阐述中的图示。其中的核心就是四重的循环,并且以结果不能大于 $level * $level作为边界控制条件。
PHP的实现相对来说简易,如果要用Java等强类型语言来实现的时候,需要先初始化整个二维数组。初始化的时候,给每个元素赋值为0,然后php中判断元素是否赋值的代码段!isset($res[$row+1][$column]),换成相应的$res[$row+1][$column]==0,即可作为判断。其余代码类似,不再赘述。
另外,近期个人事务较多,故文章发布较少,预计元旦开始会逐步恢复正常的内容发布。
——written by linhxx 2017.10.31
- 代码审查拯救世界?
- Kafka实战:从RDBMS到Hadoop,七步实现实时传输
- Apache NiFi 1.0.0测试版:邮件路由应用新型ListenSMTP
- 为什么我坚持使用 JavaScript 函数声明
- NewSQL数据库大对象块存储原理与应用
- 使用xUnit为.net core程序进行单元测试(下2)
- MongoDB + Spark: 完整的大数据解决方案
- 如何实现自然语言处理的集束搜索解码器
- PostgreSQL 使用advisory lock或skip locked消除行锁冲突, 提高几十倍并发更新效率
- 流动的数据——使用 RxJS 构造复杂单页应用的数据逻辑
- 内存泄漏的检测、解决、防止
- 大数据Hadoop快速入门教程
- 用Rust解决C语言的隐患
- GAN学习指南:从原理入门到制作生成Demo
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Flutter中Widget 、Element、RenderObject角色深入分析
- PyTorch8:损失函数
- 浅谈ThreadLocal
- 三分钟完成 ubuntu16.04初始化,Java,maven,docker环境的部署
- VMware 安装运行 deepin 虚拟机 | 体验中国深度
- 单机KVM虚拟化快照定时创建删除快照
- 批量ping脚本
- 批量ssh信任脚本
- Oracle表级备份
- Linux脚本运行报错解决方法 bad interpreter: No such file or directory
- MySQLdump里的秘密,终于被我发现了
- HTTP各种特性总览
- django查询今天,昨天,一周,分组统计月,年
- 关于 z-index,你可能一直存在误区
- Java浮点数机制及所存在的问题