这个题看似很简单:

题目:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
当看到这个题目得到时候,我的第一反应是:考虑矩阵为空,只有一行,只有一列,以及一般情况m×n矩阵。这个思维很重要,让我们无法忽视很多的边界问题。!!!以后但凡是矩阵问题,首先需要考虑特殊矩阵。
其次,我将这个问题看作是一个剥洋葱的问题。即按照这个思路打印:打印一圈,再打印一圈,再打印一圈,直到打印到最内圈。完毕!我先给出一个完整的通过检测的代码:
 class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
const int Row = matrix.size();
const int Col = matrix[].size();
vector<int> res;
if(Row|| Col)
{
if(Row == )
for(int i = ;i<Col;i++)
res.push_back(matrix[][i]);
else if(Col ==)
for(int i = ;i<Row;i++)
res.push_back(matrix[i][]);
else{
int index_row =;
int index_col =;
int start_row = ;
int start_col = ;
while((start_row <=(Row-)/) && (start_col<=(Col-)/))//???
{
while(index_col <= Col--start_col)
{
res.push_back(matrix[index_row][index_col]);
index_col++;
}
index_col--;
index_row++;
while(index_row <= Row--start_row)
{
res.push_back(matrix[index_row][index_col]);
index_row++;
}
index_row--;
index_col--;
while(index_col >=start_col && index_row != start_row)
{
res.push_back(matrix[index_row][index_col]);
index_col--;
}
index_col++;
index_row--;
while(index_row >start_row )
{
res.push_back(matrix[index_row][index_col]);
index_row--;
}
start_row++;
start_col++;
index_row = start_row;
index_col = start_col;
}
}
return res;
}
}
};

下面我来画一下这个图:

也就是我们按照图示打印所有的矩阵元素,我们没有任何技巧的情况下,所能想到的方法就是,从图中红色标记点开始,执行四趟循环,打印完四个路径。这个大思路总体是没有错误的。我们来看看这其中要注意什么问题:

问题1:从哪里开始?也就是图中红色的地方,那么红色的地方索引是多少呢?

问题2:到哪里结束?也就是最后一次执行完是什么时候,即外层的大循环执行次数怎么决定?

问题3:我们在打印的时候,四个角的位置,既属于这一行,也属于这一列,我们如何避免重复打印?

问题4:我们如何标记索引让下一次的行减少两行,列减少两列?

考虑完上述四个问题:

我之前给出了如下代码:

 class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
const int Row = matrix.size();
const int Col = matrix[].size();
vector<int> res;
if(Row|| Col)
{
if(Row == )
for(int i = ;i<Col;i++)
res.push_back(matrix[][i]);
else if(Col ==)
for(int i = ;i<Row;i++)
res.push_back(matrix[i][]);
else{
int index_row =;
int index_col =;
int start_row = ;
int start_col = ;
while((start_row <=(Row-)/) && (start_col<=(Col-)/))//???
{
while(index_col <= Col--start_col)
{
res.push_back(matrix[index_row][index_col]);
index_col++;
}
index_col--;
index_row++;
while(index_row <= Row--start_row)
{
res.push_back(matrix[index_row][index_col]);
index_row++;
}
index_row--;
index_col--;
while(index_col >=start_col )
{
res.push_back(matrix[index_row][index_col]);
index_col--;
}
index_col++;
index_row--;
while(index_row >start_row )
{
res.push_back(matrix[index_row][index_col]);
index_row--;
}
start_row++;
start_col++;
index_row = start_row;
index_col = start_col;
}
}
return res;
}
}
};

代码看似没啥差别,请注意第36行代码的变换,我们来看一下通过率:

可以看到,大部分输出都是正确的,只有后面有一些错误输出,主要原因是:我们上述代码并不适应最内层只剩一行或者只剩一列的情况。因此,我们加上了:

 index_row != start_row

也就是避免重复打印同一行或者同一列,当然,这种情况通常也只会在最内层循环产生。

再来关注的一个问题是:如何让每层洋葱循环的行和列依次减去2? 我们发现:0+4 = 1+3=row,这么说你懂了吧。

最后的一个问题是:最后一个红色开始在哪?很明显,外层循环已经给出了答案。

牛客网剑指offer第19题——顺时针打印矩阵的更多相关文章

  1. 牛客网剑指offer第13题——调整数组顺序使得奇数位于偶数前面

    题目来源:剑指offer 题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变 ...

  2. 牛客网剑指offer第21题——判断出栈序列是否是入栈序列

    题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈 ...

  3. 牛客网剑指offer第34题——找到第一个只出现一次的字符

    题目如下: 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). 先上代码: class ...

  4. 剑指offer(19)顺时针打印矩阵

    题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2, ...

  5. 【剑指Offer】19、顺时针打印矩阵

      题目描述:   输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依 ...

  6. 机器人的运动范围 牛客网 剑指Offer

    机器人的运动范围 牛客网 剑指Offer 题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大 ...

  7. 数组中只出现过一次的数字 牛客网 剑指Offer

    数组中只出现过一次的数字 牛客网 剑指Offer 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. def FindNumsAppearOnce ...

  8. 数组中出现次数超过一半的数字 牛客网 剑指Offer

    数组中出现次数超过一半的数字 牛客网 剑指Offer 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字 ...

  9. 数据流中的中位数 牛客网 剑指Offer

    数据流中的中位数 牛客网 剑指Offer 题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就 ...

随机推荐

  1. 透过现象看webpack处理css文件中图片路径转换的具体过程

    webpack是目前使用比较流行的一个前端模块打包器,前端的任何资源都被当成一个模块来处理,如图片.css文件等等.在基于webpack构建的前端项目中,一般都会配置有关css文件处理的规则,这其中也 ...

  2. Oracle 数据库 回滚

    1.打开Flash存储的权限ALTER TABLE authorization ENABLE row movement ;2.把表还原到指定时间点flashback table authorizati ...

  3. Redis异常 | DENIED Redis is running in protected mode because protected mode is enabled

    背景 今天重新搭了个redis环境,用简单的代码去测试下是否正常, @RunWith(SpringRunner.class) @SpringBootTest public class Springbo ...

  4. gulp实现自动化打包(二)

    引言 在这篇文章中我基于上一篇文章gulp的简单打包示例(一)的代码(重点,不然看的懵逼状态)来介绍gulp的自动化打包,主要是修改gulpfile.js配置文件.当我们执行gulp任务,gulp自动 ...

  5. Lambda 表达式入门,看这篇就够了

    说出来怕你们不相信,刚接到物业通知,疫情防控升级了,车辆只能出不能进,每户家庭每天可指派 1 名成员上街采购生活用品.这不是谣言,截个图自证清白,出自洛阳市湖北路街道处. 看来事态严峻,这样看似好心, ...

  6. python 不可变字典 inmutabledict的实现

    python inmutabledict的实现 关于在python中如何实现不可变字典的方法.早在pep416中,就建议python官方实现inmutabledict,但是官方否认了.理由主要是 根据 ...

  7. Win2008 远程时提示"要登录到此远程计算机,您必须被授予允许通过终端登录登录的权限"的解决方法

    问题描述 ECS Windows 2008 远程登陆时提示"要登录到此远程计算机,您必须被授予允许通过终端登录登录的权限",如下图所示: 问题分析 组策略中做了设置不允许管理员组成 ...

  8. LeetCode 218. The Skyline Problem 天际线问题(C++/Java)

    题目: A city's skyline is the outer contour of the silhouette formed by all the buildings in that city ...

  9. SpringBoot笔记一----配置文件

    1.父类指定了相应的依赖的版本,之后子工程只需要添加该依赖即可,无需指定版本,实现版本管理. 2.SpringBootApplication注解创建一个application,并且会将同包之下的文件都 ...

  10. 【OpenGL】GL_DEPTH_TEST深度测试问题

    记录一个深度测试的问题 在实现一个简单的OpenGL程序时,遇到了一个问题,深度测试总是有问题,无法正常显示,如下 正常情况为 通过调试发现屏幕空间中的所有深度值均为1. OpenGL代码如下: vo ...