`
Heis
  • 浏览: 114785 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

回旋矩阵算法题解题思路

阅读更多

原帖见:深圳一家公司面试问题,很囧

http://www.iteye.com/topic/545378

 

题目要求打印一个回旋数字矩阵

int i=5;
1  2  3  4  5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

int i=6
1  2  3  4  5   6
20 21 22 23 24  7
19 32 33 34 25  8
18 31 36 35 26  9
17 30 29 28 27 10
16 15 14 13 12 11

 

我的解题思路分析:

1.将此矩阵分解为一个一个的圈,如下图,1-20可以看成一个圈,21-32是一个圈,33-36也是一个圈。



 2.再将圈分解为四个均等的数列



 3.打印的过程中用一个二维数组存储矩阵,记录圈数当前圈的数列长度圈开始计数的数字 。如i=6,第1圈时数列长为5,开始计数的数字为0;第2圈数列长为3,开始计数的数字为20;从这些规律总结出,已知变长为i,假设当前圈数为count,则数列长step=i-1-count*2


程序代码:

package snakematrix;

/**
 * @author Heis
 * @date Dec 11, 2009
 */
public class SnakeNum {

	
	public static void main(String[] args){
		int i=6;
		SnakeNum.print(SnakeNum.fill(i));		
	}
	/**
	 * 
	 * 算法复杂度为n
	 * 以下的算法,在for循环内的一些计算是不必要的,可以用变量保存,但是为了代码更加直观,就不做优化了。
	 * 
	 * @param i 矩阵边长
	 */
	public static int[][] fill(int i){
		Long startTime=System.currentTimeMillis();
		//第几圈
		int count=0;
		//数列长度
		int step;
		//总圈数
		int all;
		//某圈开始计数的基数
		int startNum=0;
		//用于数组下标计算
		int startIndex;
		int k;
		int[][] array=null;
		if(i>0){
			array=new int[i][i];
		    all=i/2+i%2;
		    while(all>=count){
		    	step=i-1-(count<<1);
		    	count++;
		    			    	
		    	for(startIndex=count-1,k=1;k<step+1;k++){
		    		array[count-1][startIndex++]=startNum+k;	
		    	}
		    	
		    	for(startIndex=count-1,k=1;k<step+1;k++){
		    		array[startIndex++][i-count]=startNum+k+step;
		    	}
		    	
		    	for(startIndex=i-count,k=1;k<step+1;k++){
		    		array[i-count][startIndex--]=startNum+k+2*step;
		    	}
		    	
		    	for(startIndex=i-count,k=1;k<step+1;k++){
		    		array[startIndex--][count-1]=startNum+k+3*step;
		    	}
		    	startNum=4*step+startNum;
		    	
		    }
		    //当矩阵边长为基数时,打印最后一个数字
		    if(i%2>0){
		    	int mid=all-1;
		    	array[mid][mid]=i*i;
		    }
		}
		Long timeUsed=System.currentTimeMillis()-startTime;
		System.out.println("总用时:"+timeUsed+"ms");
		return array;		
	}
	
	/**
	 * 打印数组
	 * 
	 * @param array
	 */
	public static void print(int[][] array){
		if(array!=null){
			int n=array.length;
			int i=0,j;
			int count=Integer.valueOf(n*n).toString().length()+1;
			for(;i<n;i++){
				for(j=0;j<n;j++){
					System.out.printf("%"+count+"d",array[i][j]);
				}
				System.out.println();
			}
		}
	}
}

 优化后的代码:

package snakematrix;

/**
 * @author Heis
 *
 */
public class SnakeNum2 {

	public static void main(String[] args){
		int i=6;
		SnakeNum2.print(SnakeNum2.fill(i));		
	}
	/**
	 * 
	 * 算法复杂度为n
	 * @param i 矩阵边长
	 */
	public static int[][] fill(int i){
		Long startTime=System.currentTimeMillis();
		//第几圈
		int count=0;
		//转弯步数
		int step;
		//总圈数
		int all;
		//某圈开始累加的基数
		int startNum=0;
		//用于数组下标计算
		int startIndex;
		int k,cache=0;
		int[][] array=null;
		if(i>0){
			array=new int[i][i];
		    all=i/2+i%2;
		    while(all>=count){
		    	step=i-1-(count<<1);
		    	count++;
		    			    	
		    	for(startIndex=count-1,k=1;k<step+1;k++){
		    		array[count-1][startIndex++]=startNum+k;	
		    	}
		    	
		    	for(startIndex=count-1,k=1;k<step+1;k++){
		    		array[startIndex++][i-count]=startNum+k+step;
		    	}
		    	
		    	cache=(step<<1)+startNum;
		    	for(startIndex=i-count,k=1;k<step+1;k++){
		    		array[i-count][startIndex--]=cache+k;
		    	}
		    	
		    	cache=(step<<1)+startNum+step;
		    	for(startIndex=i-count,k=1;k<step+1;k++){
		    		array[startIndex--][count-1]=cache+k;
		    	}
		    	startNum=(step<<2)+startNum;		    	
		    }
		    //当矩阵边长为基数时,打印最后一个数字
		    if(i%2>0){
		    	int mid=all-1;
		    	array[mid][mid]=i*i;
		    }
		}
		Long timeUsed=System.currentTimeMillis()-startTime;
		System.out.println("总用时:"+timeUsed+"ms");
		return array;		
	}
	
	/**
	 * 打印数组
	 * 
	 * @param array
	 */
	public static void print(int[][] array){
		if(array!=null){
			int n=array.length;
			int i=0,j;
			int count=Integer.valueOf(n*n).toString().length()+1;
			for(;i<n;i++){
				for(j=0;j<n;j++){
					System.out.printf("%"+count+"d",array[i][j]);
				}
				System.out.println();
			}
		}
	}
}

 

回帖还有另外一种思路,也是用一个二维数组存储数组,按照数列顺序输出,在输出过程中判断输出的方向,可以看这里的代码http://www.iteye.com/topic/545378?page=1#1288013


  • 大小: 8.3 KB
  • 大小: 6.7 KB
  • 大小: 8.7 KB
  • 大小: 7.9 KB
2
1
分享到:
评论
1 楼 vinkeychen 2010-07-29  
向博主学习了。

相关推荐

    回旋矩阵的C实现(希望给需要的人提供帮助)

    用C语言编写回旋矩阵,可以产生任意阶的回旋矩阵,包括矩阵,以及图形的表示,直观

    输出回旋矩阵(c语言)

    回旋矩阵,也被称为螺旋矩阵或旋转矩阵,是一种特殊的矩阵排列方式。在回旋矩阵中,元素会按照顺时针或者逆时针方向螺旋式地填充。这种矩阵在某些算法和数据结构问题中有着广泛的应用,例如在图像处理、数组遍历等...

    python实现回旋矩阵方式(旋转矩阵)

    在回旋矩阵的实现过程中,思路非常关键。首先,需要创建一个n行m列的矩阵,其中n和m分别代表矩阵的行数和列数。在矩阵中按螺旋方式填充元素,需要使用四层嵌套循环,分别对应于矩阵的四个边界,即左边界、上边界、...

    C#中的回旋矩阵

    ### C#中的回旋矩阵实现 #### 知识点概览 本文将详细介绍如何在C#中实现一种特殊的矩阵——回旋矩阵。回旋矩阵是一种按照特定规则填充数字的二维数组,其特点是数字从中心向外扩展,且按照顺时针方向进行填充。此...

    求N阶回旋矩阵(C/C++)

    求N阶回旋矩阵,在给定阶数的二维数组外构建搜索边界,使用试探法求解

    基于C的回旋数

    在C语言中,理解并掌握回旋数的概念和实现方式是提升算法分析和编程技能的重要环节。本文将深入探讨回旋数的基本概念、性质以及如何使用C语言进行编程实现。 ### 回旋数基本概念 回旋数是一种数字布局,它将数字...

    Gyroklystron.rar_matlab回旋管_回旋管_电子回旋波

    回旋管,也称为回旋速调管,是一种利用电子回旋共振原理工作的微波放大器件,广泛应用于雷达、通信和粒子加速器等领域。在本文中,我们将深入探讨回旋管的基本原理、Matlab在回旋管计算中的应用以及如何理解和使用`...

    回旋算法代码

    回旋算法,也被称为旋转排序(Rotating Sort),是一种基于比较的排序算法,它通过将数组分为已排序和未排序两部分,然后逐步将未排序的部分旋转到已排序的前面来实现整体排序。这个过程就像旋转一个部分的数组,...

    Matlab 三维回旋仿真_matlab三维回旋仿真_

    在Matlab中进行三维回旋仿真是一个非常实用的技术,尤其对于物理、工程以及计算机图形学等领域的研究者和学生来说。本项目旨在为新手提供一个学习和交流的基础平台,帮助他们理解如何利用Matlab来模拟物体在三维空间...

    高考物理速度选择器和回旋加速器习题一轮复习含答案解析.doc

    9. 物理问题的解题策略 - 分析粒子受力情况,确定粒子的运动类型。 - 应用牛顿第二定律、动能定理、动量守恒定律等物理原理建立方程。 - 结合几何关系解方程,得出粒子的运动参数。 - 通过实验数据或题目给定...

    江苏百校大联考高中物理速度选择器和回旋加速器压轴题易错题-12页.pdf

    根据提供的文件信息,这是一个关于“江苏百校大联考高中物理速度选择器和回旋加速器压轴题易错题”的文档。由于内容的关键部分是高度加密或错误的OCR扫描结果,实际的物理知识点内容无法直接解析。因此,我将提供一...

    四川省德阳五中高中物理速度选择器和回旋加速器压轴题易错题.pdf

    总结以上知识点,本题涉及了高中物理中的速度选择器原理、回旋加速器的工作机制、带电粒子在磁场中的运动规律、动能和动量的关系,以及粒子在电磁场中的运动分析。这些知识点是电磁学领域的重要内容,对于理解和解决...

    java-leetcode面试题解哈希表第447题回旋镖的数量-题解.zip

    在本题解中,我们将深入探讨Java编程语言中与LeetCode面试相关的哈希表技术,特别是在解决第447题“回旋镖的数量”时的应用。哈希表是一种高效的数据结构,它允许我们在常数时间内执行查找、插入和删除操作,这在...

    回旋镖及其机械动力

    回旋镖作为一种古老而独特的投掷工具,其飞行原理一直是机械动力学领域研究的有趣课题。这种源自澳大利亚原住民的工具,因其在投掷出去后能够沿着一定的轨迹返回到投掷者手中的特性而被广泛研究。对回旋镖飞行原理的...

    C# 回旋数 控制台程序

    回旋数,也被称为螺旋数或旋转数,是一种在矩阵中按照特定顺序排列的数字模式。在C#编程中,创建一个控制台程序来展示回旋数矩阵是一种很好的练习,可以提升对数组和循环控制的理解。这个程序的核心是通过嵌套的for...

    江苏省启东中学高中物理速度选择器和回旋加速器压轴题易错题-17页.pdf

    5. **解题方法**: - **运用左手定则**:确定粒子在磁场中的运动方向。 - **动能定理**:计算粒子加速后的动能。 - **动态平衡条件**:在速度选择器中,电场力和洛伦兹力相等,解出速度。 - **几何关系**:结合...

    基于多目标遗传算法的回旋行波放大器分布式损耗参数优化.pdf

    为了深入理解这篇关于“基于多目标遗传算法的回旋行波放大器分布式损耗参数优化”的文献内容,我们将首先对标题中提到的关键概念进行解读。随后,将基于描述、标签以及部分内容,详细阐述文章中提到的关键知识点,...

    山东省平度一中高中物理速度选择器和回旋加速器压轴题易错题.pdf

    综上所述,这些题目涉及了高中物理中速度选择器、回旋加速器、质谱仪的基本原理,以及带电粒子在复合场中的运动分析,这些都是电磁学领域的核心知识点,对理解和解决类似物理问题具有指导意义。

    采用回旋线的Delta机器人轨迹优化.pdf

    本文针对Delta机器人的轨迹优化问题进行了深入研究,提出了一种新的优化方法,即通过采用回旋线-圆曲线-回旋线处理方式来规避门形路径中的突变问题,并通过实验验证了这种方法的有效性。 首先,文章回顾了机器人...

Global site tag (gtag.js) - Google Analytics