顺时针打印二维数组C语言递归,按顺时针打印矩阵

存在二种解题思路: 一种是递归解法,一种是层层递进解法

图解递归解法

bVbBz7a

如图所示, 一个5*5的矩阵

先打印最外层的圈, 然后剩余最里层3*3的矩阵, 如图.

将3*3的矩阵继续打印最外层,思路与打印最外层思路一样,我们就可以考虑使用递归实现.

最后只剩余一个元素,也可以看成一个矩阵,不过不同大小的矩阵会出现不同形状的矩阵.共3种情况, 如下图.

bVbBz7h

如图所示, 共三种情况

一个方向的情况

三个方向的情况

四个方向的情况

代码实现思路

矩阵用代码表示为二维数据

首先遍历第一行所有的元素,即图中的从左到右箭头的数据.

然后遍历最右边的元素,即最后一列数据.即图中的从上到下箭头的数据.

再遍历最后一行元素,即图中从右到左箭头的数据

最后遍历最左列的元素,即图中从下到上箭头的数据.

将剩余的矩阵构建成一个子矩阵,即新的二维数组,然后递归传递.这是关键的一步

仅剩余1行1列即是递归退出条件

图解非递归解法

bVbBz7m

如图所示,我们可以将矩阵看作层层递进的矩阵,如俄罗斯的套娃一样.

第一个套娃的起点坐标,即(0,0)

第二个套娃的起点坐标,即(1,1)

第三个套娃的起点坐标,即(2,2)

代码实现思路

设置一个起点坐标start=0, 然后按方向遍历元素,与递归遍历一样.

我们发现55的矩阵, 最后一个圈坐标为(2,2), 44矩阵最后一个圈的坐标是(1,1),得出退出条件X坐标大于2倍起点坐标.Y坐标同理可得.

for x > 2start && y > 2start, 遍历完第1层圈,再遍历第2层圈, 即start++

代码片段

//解题3思路: 每一次从最左上角打印,即坐标为(0,0),打印最外层一圈. 然后打印第二圈,即坐标:(1,1), 以次类推

//时间复杂度:O(n)

func PrintMatrixLikeSnake(matrix [][]int) []int {

if len(matrix) <= 0 {

return nil

}

rows := len(matrix)

columns := len(matrix[0])

if columns <= 0 {

return nil

}

//定义一个结果集

result := make([]int, 0)

//准备打印第一个最外层的圈,定义一个启始坐标

start := 0

//我们发现5*5的矩阵, 最后一个圈坐标为(2,2), 4*4矩阵最后一个圈的坐标是(1,1),得出退出条件X坐标大于2倍起点坐标.Y坐标同理可得.

for rows > start * 2 && columns > start * 2 {

endX := columns-1-start

endY := rows-1-start

//从左到右打印,即第一行的边

for i := start; i <= endX; i++ {

result = append(result, matrix[start][i])

}

//从最右边从上到下打印,即最右边的边

if start < endY {

for i := start+1;i <= endY; i ++ {

result = append(result, matrix[i][endX])

}

}

//从最右边从右到左打印,即最下面的边

if start < endX && start < endY {

for i := endX-1; i >= start; i -- {

result = append(result, matrix[endY][i])

}

}

//从最左边从下到上打印,即最左边的边

if start < endY - 1 {

for i := endY-1; i >= start+1; i -- {

result = append(result, matrix[i][start])

}

}

start ++

}

return result

}

总结

不管使用递归还是非递归,我们首先要找出解题的思路, 仔细观察,多画图,多演算,假设.一步一步逼进最终解.

完整代码github: 完整代码

)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值