Python 解螺旋数组

N 为 4 的螺旋数组如图所示:

输入一个正整数 N,输出以 N 为边长的螺旋矩阵。(比如上图就是 N 为 4 的结果)

分析:

1、由图可知,螺旋数组的运动方向依次 右--> 下 --> 左 --> 上 --> 右 这样的循环,在合适的条件下变换累加方向即可。

2、 1 中变换方向的条件有两个,一是遇到数组边界;二是下一位置被其他数占据,比如 数字 12 的下一位 13, 按照 上 运动方向来说,13 会填在 1 的位置,但 1 这个位置已经被占据,所以得变换方向。

明白以上主要的两点就有了解题的方向。接下来探讨一些细节:

3、 方向的变换可以用 python 中的 % (求余) 循环实现,记录 4 个方向 derections,同时记录一个变量 mark ,随着 mark 的自增,(mark % 4) 的值为 [0,1,2,3,0,1,2,3...] 循环,这样达到循环获取方向的目的


def derection(self, mark):
    around = [
      [self.row, self.col+1],
      [self.row+1, self.col],
      [self.row, self.col-1],
      [self.row-1, self.col]
      ]
    return around[mark%4]

4、寻找下一个位置,已知当前的位置与当前的方向,获取下一个位置,并判断是否变换方向。

# 针对目前位置,获取下一位置的 行列 数
    # 下一位置为边界则更换方向
    # 下一位置已经有元素则更换方向
    def next(self):
        # 下一位置
        i = self.derection(mark=self.mark)
        # 判断是否更换方向,不更换则更新 self.row / self.col
        if -1 not in i and self.max_row not in i:
            if self.matrix[i[0]][i[1]] is None:
                self.row,self.col = i
                return None
        # 更换方向
        self.mark += 1
        return self.next()
完整代码:

# coding=utf-8
'''
今天这题,看起来挺简单,实际写出来并不容易。在以前公司我曾把它做过招聘的笔试题,结果惨不忍睹,不得不拿掉。
输出如图的螺旋矩阵:
 1   2   3   4
12  13  14   5
11  16  15   6
10   9   8   7
附加题:
输入一个正整数 N,输出以 N 为边长的螺旋矩阵。(比如上图就是 N 为 4 的结果)
'''

class Spiral:

    def __init__(self, N):

        self.matrix = [[None for i in range(N)] for j in range(N)]
        self.row = 0
        self.col = 0
        self.max_row = N
        self.mark = 0

    # 按需取出对应方向
    def derection(self, mark):

        around = [
        [self.row, self.col+1],
        [self.row+1, self.col],
        [self.row, self.col-1],
        [self.row-1, self.col]
        ]

        return around[mark%4]

    # 针对目前位置,获取下一位置的 行列 数
    # 下一位置为边界则更换方向
    # 下一位置已经有元素则更换方向
    def next(self):
        # 下一位置
        i = self.derection(mark=self.mark)
        # 判断是否更换方向,不更换则更新 self.row / self.col
        if -1 not in i and self.max_row not in i:
            if self.matrix[i[0]][i[1]] is None:
                self.row,self.col = i
                return None
        # 更换方向
        self.mark += 1
        return self.next()


    def solution(self):
        # 逐一取出 1 到 n^2 值
        for i in range(1,self.max_row**2+1):
            # 按行列赋值
            self.matrix[self.row][self.col] = i
            # 退出条件
            if i == self.max_row**2:
                break
            # 更新行列值
            self.next()

        # 打印结果
        for r in self.matrix:
            for c in r:
                print('{0:^{1}}'.format(c,self.max_row), end=' ')

            print('\n')


s = Spiral(10)
s.solution()


posted @ 2017-06-27 22:14  zx576  阅读(736)  评论(0编辑  收藏  举报