九度OJ剑指offer中关于顺时针输出矩阵的问题分析
2015-11-04 17:16
309 查看
顺时针输出矩阵,具体题目要求是将一个矩阵按照顺时针的顺序从矩阵边框开始依次遍历矩阵中的所有元素。题目要求乍一看可能觉得十分简单,也没有涉及十分复杂的数据结构,但是分析起来还是十分有意思的。
首先我们先看看要解决这个问题的基础:螺旋矩阵,不管是正螺旋还是反螺旋,其实质是一样的。螺旋矩阵的相关介绍这里就直接引用百科的相关描述。
螺旋矩阵的链接
下面思考下如何将螺旋矩阵和这个问题结合起来,其实螺旋矩阵的实质就是矩阵中元素的变化规律,我们如果结合了相关规律将我们需要输出的数组封入一个临时数组,最后将数组输出,这个问题就解决了。
然而螺旋矩阵中的变化规律不是简单就能描述的,我看别人写的代码的时候,加了注释都不一定能看懂。所以解决一个问题最重要的是要自己掌握解决问题的基本思路,否则你编码也只能是照本宣科,看不到本质是十分可怕的,所以我是十分鼓励大家去多自己研究下算法内部的运行机理的,这样才能融会贯通,可以做到举一反三。
螺旋矩阵规律分析:首先这里我们要引入x轴和y轴的概念,这样就可以直接和数学解析几何相结合,这个问题我们要解决的问题其本质就是矩阵中元素的运行轨迹,如果读者将螺旋矩阵的运行轨迹画出来,你就会很容易发现,两条对角线将这个矩阵分为四块,而这四块中的元素的运行规律是一样的,这就是为什么要引入解析几何的原因,将矩阵分为四块后,我们要分析下相关规律,这种变化只有四种可能(x++,y++,x--,y--),还有一个很重要的问题就是寻找下四个区域中分割线的归属问题,这个细节在程序中是很重要的,假如你的程序你觉得很正常就是会报错,你可能就要检查下边界上的“=”是否加错了位置,对于详细信息我会在源码中进行注释。
解决了螺旋矩阵,剩下就是与螺旋矩阵的顺序依次插入到临时数组中,这里我是选择的从内部到外部的顺序,如果选择从内到外,我在分析问题规律的时候发现会有冲突点,这一点上就增加了这个程序的困难度。
矩阵中开始点的选择也是有区别的,这取决于你输入矩阵的规模是奇数还是偶数,如果是奇数,这个没有问题,开始点就是中心点,但是如果规模是偶数的,矩阵并没有中心点,开始点是相对中心点的左下方点,这个点的选择读者可以自己归纳出来,至于证明为什么是这个点,笔者还没有进行过尝试,读者如果有兴趣不妨可以试试。
相关代码如下:
首先我们先看看要解决这个问题的基础:螺旋矩阵,不管是正螺旋还是反螺旋,其实质是一样的。螺旋矩阵的相关介绍这里就直接引用百科的相关描述。
螺旋矩阵的链接
下面思考下如何将螺旋矩阵和这个问题结合起来,其实螺旋矩阵的实质就是矩阵中元素的变化规律,我们如果结合了相关规律将我们需要输出的数组封入一个临时数组,最后将数组输出,这个问题就解决了。
然而螺旋矩阵中的变化规律不是简单就能描述的,我看别人写的代码的时候,加了注释都不一定能看懂。所以解决一个问题最重要的是要自己掌握解决问题的基本思路,否则你编码也只能是照本宣科,看不到本质是十分可怕的,所以我是十分鼓励大家去多自己研究下算法内部的运行机理的,这样才能融会贯通,可以做到举一反三。
螺旋矩阵规律分析:首先这里我们要引入x轴和y轴的概念,这样就可以直接和数学解析几何相结合,这个问题我们要解决的问题其本质就是矩阵中元素的运行轨迹,如果读者将螺旋矩阵的运行轨迹画出来,你就会很容易发现,两条对角线将这个矩阵分为四块,而这四块中的元素的运行规律是一样的,这就是为什么要引入解析几何的原因,将矩阵分为四块后,我们要分析下相关规律,这种变化只有四种可能(x++,y++,x--,y--),还有一个很重要的问题就是寻找下四个区域中分割线的归属问题,这个细节在程序中是很重要的,假如你的程序你觉得很正常就是会报错,你可能就要检查下边界上的“=”是否加错了位置,对于详细信息我会在源码中进行注释。
解决了螺旋矩阵,剩下就是与螺旋矩阵的顺序依次插入到临时数组中,这里我是选择的从内部到外部的顺序,如果选择从内到外,我在分析问题规律的时候发现会有冲突点,这一点上就增加了这个程序的困难度。
矩阵中开始点的选择也是有区别的,这取决于你输入矩阵的规模是奇数还是偶数,如果是奇数,这个没有问题,开始点就是中心点,但是如果规模是偶数的,矩阵并没有中心点,开始点是相对中心点的左下方点,这个点的选择读者可以自己归纳出来,至于证明为什么是这个点,笔者还没有进行过尝试,读者如果有兴趣不妨可以试试。
相关代码如下:
package jiuduOJ; import java.util.Scanner; /** * 按顺时针顺序打印矩阵,这是九度oj中关于剑指offer的一道题,我是结合了螺旋矩阵去解决这个问题的 *@author:Mr.wang *@version:1.0 *@time:2015/11/4 */ public class HelixMatrix { public static void main(String[] args) { System.out.print("请输入一个矩阵的规模::"); Scanner sc = new Scanner(System.in); int size = sc.nextInt(); int y = size/2; int x = (size%2==0?size/2-1:size/2);//区分奇数偶数情况 int count = 0;//临时矩阵的计数器 int[][] ar = new int[size][size]; int[] t = new int[size*size]; for(int i = 0; i <= size-1; i++)//键入一个测试矩阵 { for(int j =0; j <= size-1; j++) { ar[i][j] = sc.nextInt(); } } for(int i = size*size;i >= 1;i--) { if(x >= y&&x <= size -y-1)//四个分支对应的四个区域,if中的条件对应于相关对角线的解析式 { t[count] = ar[y][x]; count++; x--;//位置移动规律 } else if(x < y&&x < size-y-1) { t[count] = ar[y][x]; count++; y++; } else if(x < y&&x >= size-y-1 ) { t[count] = ar[y][x]; count++; x++; } else if(x >= y&&x > size-y-1) { t[count] = ar[y][x]; count++; y--; } } for(int k = size*size-1; k >= 0; k--) System.out.print(t[k]+" "); } }
相关文章推荐
- js原生设计模式——3简单工厂模式\简单工厂模式封装简单对象
- Javascript Closure
- js原生设计模式——3简单工厂模式\js面向对象编程实例
- css3动画引入prefixfree.js的优缺点
- js原生设计模式——2面向对象编程之继承—多继承
- jQuery官方教程之频繁被问的问题汇总
- java.nio.ByteBuffer用法小结
- js原生设计模式——2面向对象编程之继承—原型继承(类式继承的封装)
- 关于jQuery中的$.ajax()使用过程中的一些感悟
- Cas登录页面修改——jsp页面中文乱码
- js原生设计模式——2面向对象编程之继承—new+call(this)组合式继承
- 【笔记】web响应式设计:HTML5和CSS3实战 第一章~第三章
- js原生设计模式——2面向对象编程之继承—call(this)构造函数式继承
- 【解决】CDH5运行MapReduce的乱码
- js原生设计模式——2面向对象编程之继承—new类式继承
- GridControl控件的数据显示的样式控制(转)
- jquery源码分析
- CSS属性选择器参考表
- js原生设计模式——2面向对象编程之js原生的链式调用
- CSS十六种基本颜色