论坛首页 综合技术论坛

关于螺旋矩阵问题的新思路

浏览 17675 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-12  
用Java写的递归方式(行和列不同也可),比较匆忙,代码没优化,劳烦各位凑活着看看:

public class SpireMatix {

	enum Direction {
		FORWARD, BACKWARD, DOWN, UP
	}

	class CycleBoundary {
		int minX, maxX;
		int minY, maxY;

		public CycleBoundary(int minX, int maxX, int minY, int maxY) {
			this.minX = minX;
			this.maxX = maxX;
			this.minY = minY;
			this.maxY = maxY;
		}
	}

	int[][] matrix;
	int blankNum;
	int row = 0, col = 0;
	CycleBoundary cycleBoundary;

	public SpireMatix(int row, int col) {
		matrix = new int[row][col];
		this.row = row;
		this.col = col;
		cycleBoundary = new CycleBoundary(0, this.row - 1, 0, this.col - 1);
		blankNum = row * col;

	}

	public void print(int start) {
		setMatrix(this.matrix, 0, 0, start, Direction.FORWARD);
		prtMatrix();
	}

	private void setMatrix(int[][] matrix, int x, int y, int start,
			Direction direction) {

		matrix[x][y] = start;

		if (blankNum == 1) {
			return;
		}

		start++;
		blankNum--;

		int nextX = x, nextY = y;

		switch (direction) {
		case FORWARD:
			nextY++;
			if (nextY == cycleBoundary.maxY) {
				direction = Direction.DOWN;
				cycleBoundary.maxY--;
				// nextX++;
			}
			break;
		case BACKWARD:
			nextY--;
			if (nextY == cycleBoundary.minY) {
				direction = Direction.UP;
				cycleBoundary.minY++;
			}
			break;
		case DOWN:
			nextX++;
			if (nextX == cycleBoundary.maxX) {
				direction = Direction.BACKWARD;
				cycleBoundary.maxX--;
			}
			break;
		case UP:
			nextX--;
			if (nextX == cycleBoundary.minX + 1) {
				direction = Direction.FORWARD;
				cycleBoundary.minX++;
			}
			break;
		}

		setMatrix(matrix, nextX, nextY, start, direction);

	}

	private void prtMatrix() {
		for (int i = 0; i < this.row; i++) {
			for (int j = 0; j < this.col; j++) {
				System.out.print(matrix[i][j] + "   ");
			}
			System.out.println();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SpireMatix matrix = new SpireMatix(10, 10);
		matrix.print(1);

	}

}
0 请登录后投票
   发表时间:2011-05-13   最后修改:2011-05-13
肯定是算公式嘛
要是开个二维数组然后按照顺序一个一个赋值多无聊,缺少那啥含量嘛
而且要是让你算100000*100000的,内存也不够

公式方法其实很简单
1.首先判断处于从外到内的第几圈(O(1))
2.计算这一圈从数字几开始(O(1))
3.然后判断处于某一圈的上下左右的哪条边第几个(O(1))

那就OK了,不考虑2的查表那就是O(1)的。

0 请登录后投票
   发表时间:2011-05-23  
以前的帖子讨论过,现在这题目还这么火爆。。
http://www.iteye.com/topic/545378?page=7#1307247
0 请登录后投票
   发表时间:2011-06-18   最后修改:2011-06-18
我的思路是这样的:把一个矩阵的每个元素当做一个点,每个点有3个方向可以走,不过结合当前的走向和位置,能唯一确定下一个走向,如:一个向右走的点,要么继续向右走,要么转向下走,要么无路无走;一个向上走的点,要么继续向上走,要么转向右走,要么无路可走;所以我说一个点有3个方向可以选择:这样的话,定义一个方向的enum,其元素有:RIGHT,DOWN,LEFT,UP,NOWHERE;因为每个方向上根据当前位置可以确定下一个走向,当没有走向时,即NOWHERE时,我们就完成一次螺旋了,指定行,列就可以了,要是再指定不同的开始方向,也好改代码,代码如下:
public class SpireMatrix {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Point p = new Point(4, 6, Go.RIGHT);
		p.fill();
		p.matrix();
	}

	private static class Point {
		int row = 0, column = 0;
		Go go;
		public static int value = 1;
		public static int maxRow, maxColumn;
		static int[][] matrix;

		public static int increase() {
			return ++value;
		}

		public Point(int row, int column, Go initialDirection) {
			if (row < 1)
				maxRow = 1;
			maxRow = row - 1;
			if (column < 1)
				maxColumn = 1;
			maxColumn = column - 1;
			this.go = initialDirection;
			matrix = new int[row][column];
		}

		public void fill() {
			if (go.equals(Go.NOWHERE))
				return;
			matrix[row][column] = value;
			Point p = go.decideWhereToGo(this);
			p.fill();
		}

		public void matrix() {
			for (int i = 0; i < matrix.length; i++) {
				for (int j = 0; j < matrix[i].length; j++)
					System.out.printf("%4d", matrix[i][j]);
				System.out.println();
			}
		}
	}

	private enum Go {
		RIGHT, DOWN, LEFT, UP, NOWHERE;

		private Go() {
		}

		public Point decideWhereToGo(Point p) {
			int row = p.row;
			int column = p.column;
			Go go = p.go;
			switch (go) {
			case RIGHT:
				if (column == Point.maxColumn
						|| Point.matrix[row][column + 1] != 0) {
					if (p.row == Point.maxRow
							|| Point.matrix[row + 1][column] != 0)
						p.go = NOWHERE;
					else {// turn DOWN
						p.row++;
						p.go = DOWN;
					}
				} else {// continue go RIGHT
					p.column++;
				}
				Point.value = Point.increase();
				return p;
			case DOWN:
				if (row == Point.maxRow || Point.matrix[row + 1][column] != 0) {
					if (p.column == 0 || Point.matrix[row][column - 1] != 0) {
						p.go = NOWHERE;
					} else {// turn LEFT
						p.column--;
						p.go = Go.LEFT;
					}
				} else {
					// continue go DOWN
					p.row++;
				}
				Point.value = Point.increase();
				return p;
			case LEFT:
				if (column == 0 || Point.matrix[row][column - 1] != 0) {
					if (p.row == 0 || Point.matrix[row - 1][column] != 0) {
						p.go = NOWHERE;
					} else {// turn UP
						p.row--;
						p.go = Go.UP;
					}
				} else {
					// continue go LEFT
					p.column--;
				}
				Point.value = Point.increase();
				return p;
			case UP:
				if (row == 0 || Point.matrix[row - 1][column] != 0) {
					if (p.column == Point.maxColumn
							|| Point.matrix[row][column + 1] != 0) {
						p.go = NOWHERE;
					} else {// turn RIGHT
						p.column++;
						p.go = RIGHT;
					}
				} else {// continue go UP
					p.row--;
				}
				Point.value = Point.increase();
				return p;
			default:
				return p;
			}
		}
	}
}
0 请登录后投票
   发表时间:2011-11-05  
数学思维解决此问题,高效!
#include<iostream.h>
#include <iomanip.h>

void main()
{
	int num = 7;       // num = 2*i + 1
	int number = num;
        int matrix[7][7]; 
	int start = num * num;
	int index = 0;


	while(num > 0)
	{
		//给第一行赋值
		for(int i = num-1+index; i >= index; i--)  
			matrix[index][i] = start--;
		
		start++;//恢复start的值给第一列赋值
		for (int j = index; j < num+index; j++)
			matrix[j][index] = start--;
		
		start++;//恢复start的值给最后一行赋值
		for (int k = index; k < num+index; k++)
			matrix[num-1+index][k] = start--;
		
		start++;//恢复start的值最后一列赋值。此时第一轮结束。最后一列只有num-1个元素被赋值
		for (int l = num-1+index; l > index; l--)
		matrix[l][num-1+index] = start--;
		
		num = num - 2;
		index++;
	}


	//打印二维数组
	for(int x = 0; x < number; x++)
	{
		for(int y = 0; y < number; y++)
			cout<<setw(4)<<matrix[x][y];
		cout<<endl;
	}
}
0 请登录后投票
   发表时间:2012-01-30  
矩阵--->二维数组
(0,0),(0,1),(0,2),(0,3),(0,4)
(1,0),(1,1),(1,2),(1,3),(1,4)
(2,0),(2,1),(2,2),(2,3),(2,4)


边缘问题,将统计数组长度,生成自然数,对应到矩阵中打印出来即可
0 请登录后投票
   发表时间:2012-02-02  
locmap = [lambda x: (x[0], x[1] + 1), lambda x: (x[0] + 1, x[1]), lambda x: (x[0], x[1] - 1), lambda x: (x[0] - 1, x[1])]

class Matrix(object):
    def __init__(self, w, h):
        self.w = w
        self.h = h
        self.matrix = [[0] * w for i in range(h)]
        
    def inRange(self, loc):
        return 0 <= loc[1] < self.w and 0 <= loc[0] < self.h
    
    def isEmpty(self, loc):
        return self.matrix[loc[0]][loc[1]] == 0

    def nextloc(self, loc, dirc):
        next = locmap[dirc](loc)
        if self.inRange(next) and self.isEmpty(next):
            return next, dirc
        else:
            return self.nextloc(loc, (dirc + 1) % 4)
        
    def format(self):
        loc = (0, -1)
        dirc = 0
        
        for i in range(1, self.w * self.h + 1):
            loc, dirc = self.nextloc(loc, dirc)
            self.matrix[loc[0]][loc[1]] = i
            
        for i in range(self.h):
            print(self.matrix[i])


Matrix(5, 4).format()


[1, 2, 3, 4, 5]
[14, 15, 16, 17, 6]
[13, 20, 19, 18, 7]
[12, 11, 10, 9, 8]
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics