java二维数组遍历后转为一维数组_算法基础面试题之逆时针遍历二维数组(螺旋矩阵)...

edf4694b15d65d57756fe237d00eea4a.png
考题:如何把一个二维数组逆时针的存到一个一维数组里面

笔者在面试的时候遇到了一道题,面试官让我用熟悉的语言把一个二维数组逆时针的存到一个一维数组里面去。很遗憾当时没有做出来(残念,大家也知道如果算法面试的时候,如果编程题没做出来,基本凉凉),事后发现这道题其实很简单...所以笔者在此把自己的解题思路分享给大家,同时也以此为戒,来时时告诉自己编程基础的重要性。

ebabb3c556b87358c0577e7215bb608f.png
二维数组的逆时针遍历

神奇的是面试官当时居然提示我应该用规则来解这道题,但是我第一时间想到的是利用矩阵的转置。因为逆时针遍历上面这个数组相当于顺时针遍历下面这个数组↓:

2eb2f1fec562cd87522fac96f7820886.png
二维数组的正时针遍历

大家知道一个二维的数组其实就是一个矩阵,而上面这个过程恰好符合矩阵的转置运算,我们来回顾一下矩阵的转置:

设A为m×n阶矩阵(即m行n列),第i 行j 列的元素是a(i,j),
即:把m×n矩阵A的行换成同序数的列得到一个n×m矩阵,此矩阵叫做A的转置矩阵。

我们拿到原始矩阵的转置后,我们可以观察到这个新的矩阵的第一行就是我们想要结果的前n个元素,那么这个矩阵可以被分解成2个部分,如下图所示,上半部分是我们想要答案的部分结果,下半部分则还需要进一步的被处理:

a62cda7abde72d45d53c2048a55e487d.png
矩阵分解的过程

实际上这种操作在Python就是很简单的切片、分片与索引的操作,我们先来回顾一下numpy的切片与引索:

ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
import 

拿到剩余的部分后观察发现,这个剩余部分的处理其实是原问题的子问题,而遇到这样的问题我们通常都是利用循环、递归或者动态规划的方式来处理:

c08611fc37ac973675b3ff35db03b003.png
剩余部分的处理

同前面拿到的n个元素的思路一样,为了让12、13也很方便的拿出来,我们再次将这个剩余的部分转置得到下一个的矩阵:

123f5a14c3d4e74b62fab13f6f12ec39.png
剩余部分的转置

为了统一处理这个问题的方法,我们还是把子问题都转换顺时针。而且发现这个剩余部分的转置只需要把行的顺序反过来,那么这个子问题又回到了顺时针,如下:

import 

dd4eb945610a1ec516c6794cbb703ed5.png
行倒序

到了这一步我们已经可以完整的总结出这道题的解题思路(其中的一种解题思路)了:

  • 逆时针问题可以通过矩阵转置来转换为顺时针问题
  • 转换到顺时针问题后,拿出第一行,剩余的子问题重复这个流程

完整的解题代码:

面试过程也需要注意代码的规范,面试官在考查你解题思路的同时也会考查你写代码的习惯,比如: 函数、变量命名、异常处理等。

import 

不用numpy的版本:

def 

最后我们总结一下,这道题虽然算是比较简单的算法题,但是这个解题方法(猜测面试官真正想看到的)还是包含了几个非常重要的基础知识点:

  • 矩阵的基本性质、运算;
  • Python中数组的基本操作或者Numpy的切片、索引操作;
  • 将复杂问题简化为处理子问题的思维方式;
  • 写代码的习惯与规范。

笔者当时没有解出来,所以事后就做了详细思考与尝试,不断从失败中总结经验,下次一定不要犯同样的错误。

希望大家面试成功、之后步步高升。

82e1c015f0f3cd9f1eec1ec58d19d271.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值