【面试题】输出数组的问题
来源:互联网 发布:宏源证券交易软件 编辑:程序博客网 时间:2024/06/09 20:46
题目:输出这样的数组:
03 05 08 14 16
04 09 13 17 22
10 12 18 21 23
11 19 20 24 25
当然你的问题不应该是一位数输出 “1”还是“01”。
这是一类型问题,把数字按照一定的顺序(或者图案、路径)输出,我们姑且称之为“PrintArray”问题吧。
--------------------------------------------------------------------------
遇到这个问题的时候,我们的大部分人会想着怎样在print的时候找到对应的某个位置是那个数,这样的方法也不是说就不行,反正我实在是懒得伤脑筋。那天遇到这个问题的时候,我瞬间想到的是Iterator,熟悉Java集合框架或者STL的朋友肯定对此有所了解:迭代模式。
我们把上面的数看成一个集合,这个集合的元素当然也是需要包装一下的,因为我们在知道元素的值的同时,还想知道它究竟对应于输出时的位置(x,y)。从程序设计的角度讲,元素的迭代方式(即顺序或者路径等等)应该由迭代器决定,元素基本上只是一个pojo,不过我这里只做了简单的实现,并没有把二者分开。
让我们回想一下,STL当中定义的迭代器的类型共有四种,分别是random(随机访问,比如数组,访问时间O(1)),bidirect(双向),forward(单向),input。对于本题来说,bidirect是比较容易实现的,算法也是O(1),而random的话,实际上可以通过执行i次bidirect从形式上实现,但复杂度就成为O(n)了,所以我们只考虑bidirect的情况。
对于bidirect来说,forward和backward实际上经常是逆操作,我下面列出的代码只给出forward,backward的代码看大家自己的兴趣了。
class Iter {boolean direction = true;int cur = 1;int x = 0;int y = 0;int N;int sqrN;public Iter(int N) {this.N = N;this.sqrN = (int) Math.sqrt((double) N);if (sqrN * sqrN != N) {throw new RuntimeException();}}public boolean forward() {if (cur == N) {return false;}if (direction) {if (x == sqrN - 1) {y += 1;direction = false;} else if (y == 0) {x += 1;direction = false;} else {x += 1;y -= 1;}} else {if (y == sqrN - 1) {x += 1;direction = true;} else if (x == 0) {y += 1;direction = true;} else {x -= 1;y += 1;}}cur++;return true;}}这里的N是输出的最大值,我们要求它是一个完全平方数,当N不符合要求时,抛异常。
代码中的direction可并不是指输出的方向,而是数字在输出时,按照数字顺序输出时呈现在路径上的顺序:从左下角到右上角,或是从右上角到左下角。
这时候有人说我们是要输出这个数组啊,没问题,下面给出main的代码:
public class PrintArray {public static void main(String[] args) {Iter it = new Iter(25);int[][] array = new int[it.sqrN][it.sqrN];array[0][0] = it.cur;while (it.forward()) {array[it.y][it.x] = it.cur;//System.out.println(it.cur + "--(" + it.x + "," + it.y + ")");}for (int i = 0; i < it.sqrN; i++) {for (int j = 0; j < it.sqrN; j++) {System.out.print(String.format("%02d", array[i][j]) + "\t");}System.out.println();}}}我们先通过迭代把所有需要输出的数存入一个sqrtN阶的数组中,然后依次打印就行了。你可以把N取得很大,比如我取它为64,那么结果就像这样:
01 02 06 07 15 16 28 29
03 05 08 14 17 27 30 43
04 09 13 18 26 31 42 44
10 12 19 25 32 41 45 54
11 20 24 33 40 46 53 55
21 23 34 39 47 52 56 61
22 35 38 48 51 57 60 62
36 37 49 50 58 59 63 64
---------------------------------------------------------------------------------------
这个思路实际上可以用于很多数组输出的问题,比如:
01 28 27 26 25 24 23 22
02 29 48 47 46 45 44 21
03 30 49 60 59 58 43 20
04 31 50 61 64 57 42 19
05 32 51 62 63 56 41 18
06 33 52 53 54 55 40 17
07 34 35 36 37 38 39 16
08 09 10 11 12 13 14 15
逆时针旋转的形状输出,那么你只需要修改一下Iter即可。
class Iter2 {enum Direction {UP, DOWN, LEFT, RIGHT}Direction direction = Direction.DOWN;int cur = 1;int x = 0;int y = 0;int N;int sqrN;int maxX;int maxY;int minX;int minY;public Iter2(int N) {this.N = N;this.sqrN = (int) Math.sqrt((double) N);if (sqrN * sqrN != N) {throw new RuntimeException();}maxX = sqrN - 1;maxY = sqrN - 1;minX = 0;minY = 0;}public boolean forward() {if (cur == N) {return false;}switch (direction) {case DOWN:if (++y == maxY) {direction = Direction.RIGHT;++minX;} else {}break;case LEFT:if (--x == minX) {direction = Direction.DOWN;++minY;}break;case RIGHT:if (++x == maxX) {direction = Direction.UP;--maxY;}break;case UP:if (--y == minY) {direction = Direction.LEFT;--maxX;}break;default:break;}cur++;return true;}}那么实际上,既然知道了iter可以按照要求输出这些数字,就可以给它配备算法。这种做法有点儿类似STL的算法设计模式。
通过简单的修改forward的代码就可以让数字按照各式各样的图案输出。为了增加趣味,我们让上面的逆时针输出点儿别的:
- 【面试题】输出数组的问题
- 【百度面试题】循环有序数组的查找问题
- 面试题:数组按列排序的问题
- 【百度面试题】循环有序数组的查找问题
- 【百度面试题】循环有序数组的查找问题
- 数组相关的面试题
- 关于数组的面试题
- 有关数组的面试题
- 数组的常见面试题
- 关于数组的面试题
- 关于数组的面试题
- 面试题--1 数组的几道面试题
- 面试题-找出数组中第k大小的数,输出数所在的位置
- 笔试题&面试题:找出一个数组中第m小的值并输出
- java面试题:输出旋转数组的最小元素(剑指offer)
- 某面试题--数组排序问题
- 华为面试题三维数组问题
- 北美微软面试题---数组问题
- 零基础学小议LLVM
- JAVA中的向上转型与向下转型
- javaweb程序中,普通的java类,不是servlet类读取资源文件的方式
- cocos2d-x 多点触控总结
- pat advanced 1013
- 【面试题】输出数组的问题
- 字母图形
- git 命令
- Java中子类和父类间的调用关系
- UVa:1424 Salesmen
- websphere6.1 配置sqlserver数据源
- java加载文件的方式
- KeychainItemwrapper生成设备唯一标识
- UVa 305 / POJ 1012 Joseph (如何得到约瑟夫环的下一个位置?)