Snail Sort (Codewars 4kyu Python)

题目:

Given an n x n array, return the array elements arranged from outermost elements to the middle element, traveling clockwise.
array = [[1,2,3],
[4,5,6],
[7,8,9]]
snail(array) #=> [1,2,3,6,9,8,7,4,5]
For better understanding, please follow the numbers of the next array consecutively:
array = [[1,2,3],
[8,9,4],
[7,6,5]]
snail(array) #=> [1,2,3,4,5,6,7,8,9]
This image will illustrate things more clearly:
Snail Sort (Codewars 4kyu Python)_第1张图片
NOTE: The idea is not sort the elements from the lowest value to the highest; the idea is to traverse the 2-d array in a clockwise snailshell pattern.
NOTE 2: The 0x0 (empty matrix) is represented as en empty array inside an array [[]].

我的思路:

题目就是让我们按顺时针方向,由外向里获取二维数组中的数字。

数组是正方形的,获取一圈数字后剩下的还是正方形。我构造了两个function,一个是 get_outer() ,用来获取最外圈数字;一个是 cut_outer() ,用来把最外圈削掉,变成一个新的小一圈的正方形。当正方形边长大于等于3时,循环获取和削除的过程,最后边长为1或2时再获取一次。

我的解答:

def snail(snail_map):
    result = []
    while len(snail_map) >= 3:
        result = result + get_outer(snail_map)
        snail_map = cut_outer(snail_map)
    result = result + get_outer(snail_map)
    return result
    
def get_outer(map):
    n = len(map)
    if n == 1:
        return map[0]
    first = map[0]
    second = []
    if n >= 3:
        for i in range(1,n-1):
            second.append(map[i][n-1])
    third = map[n-1]
    third.reverse()
    fourth = []
    if n >= 3:
        for j in range(1,n-1):
            fourth.append(map[j][0])
    fourth.reverse()
    return first + second + third + fourth
    
def cut_outer(map):
    n = len(map)
    new = []
    for i in range(1,n-1):
        new.append(map[i][1:n-1])
    return new

Most Clever:

做完题目看一下题后投票clever最多的答案:

def snail(array):
    return list(array[0]) + snail(zip(*array[1:])[::-1]) if array else []

大佬一句话就解决了。

其中 zip() 我没有见过,查了一下:

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

自己试一下:
Snail Sort (Codewars 4kyu Python)_第2张图片
由于是规整的二维数组,zip() 相当于把数组沿“左上-右下“”对角线翻转,然后 [::-1] 相当于沿垂直中线翻转,两个操作合起来相当于顺时针旋转90度。

用递归不断调用自己,每一次调用都先将第一行加入list,然后把矩阵顺时针旋转90度。非常巧妙。

总结:

学会了 zip() 的用法,Most Clever的答案很巧妙地控制矩阵变形,过程简单而且形象。

你可能感兴趣的:(刷题,#,Codewars)