第29题:LeetCode54:Spiral Matrix螺旋矩阵
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
考点
1.抽象问题画图
2.复杂问题分解成简单问题
思路
1.把矩阵看成若干个顺时针方向的圈组成
1.1 每个圈的起点都是(start,start) ,横纵坐标相等
1.2 对于5*5的矩阵,最后一圈只有一个数字(2,2),5>2*2.对于6*6的矩阵,最后一圈有四个数字,左上角起点(2,2),6>2*2
1.3 横纵坐标都小于行列数的1/2,才能作为起点。下标从0开始,所以是小于,不是小于等于
循环条件 while ( cols > start << 1 && rows > start<<1)
2.打印矩阵最里面的一圈,可能只需要三步、两步、甚至一步
2.1 定义起点横纵坐标的终止位置
终止列号:EndX = cols - 1 - start;
终止行号:EndY = rows - 1 - start;
数学意义:
边界坐标 = 最后一列坐标 - 已经打印过的列数=(cols-1)-(start-0)= cols - 1 - start;

2.2 从左到右打印第一行

第一步总是需要的,
循环条件:i=start;i<=EndX;i++
print num[start][i]
2.3 从上到下打印最后一列:

第二步条件:至少两列, start<EndY
循环条件:i=start+1;i<=endY;i++
print num[i][EndX];
2.4 从右到左打印最后一行

第三步条件:至少两行两列 start<EndX && start < EndY
循环条件: i=EndX-1;i>=start;i--
print num[EndY][i]
2.5 从下到上打印第一列
第四部条件:至少三行两列 start<EndX&&start<EndY-1

循环条件: i=EndY-1;i>start;i--
print num[i][start]
代码
leecode
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
//0.函数入口判断
vector<int> temp;
if(!matrix.size())
return temp;
//1.计算行列数
int start= 0;
int rows=matrix.size();
int cols=matrix[0].size();
vector<int> ret(rows*cols);
ret.clear();
//2.打印循环
while(start<<1<rows&&start<<1<cols)
{
//打印
{
//2.1 设置边界值
int EndX=cols-1-start;
int EndY=rows-1-start;
//2.2 第一步从左到右打印
for(int i = start;i<=EndX;i++)
{
ret.push_back(matrix[start][i]);
}
//2.3 第二步从上到下打印 条件至少两行 start<EndY
if(start<EndY)
{
for(int i = start+1;i<=EndY;i++)
{
ret.push_back(matrix[i][EndX]);
}
}
//2.4第三步 从右往左 至少两列两行 start<EndX&&start<EndY
if(start<EndX&&start<EndY)
{
for(int i=EndX-1;i>=start;i--)
{
ret.push_back(matrix[EndY][i]);
}
}
//2.5第四步 从下往上 至少三行两列 start<EndX&&start<EndY-1
if(start<EndX&&start<EndY-1)
{
for(int i = EndY-1;i>start;i--)
{
ret.push_back(matrix[i][start]);
}
}
}
start++;
}
return ret;
}
};
nowcoder
//1.计算行列数
int start= 0;
int rows=matrix.size();
int cols=matrix[0].size();
vector<int> ret(rows*cols);
ret.clear();
//2.打印循环
while(start*2<rows&&start*2<cols)
{
//打印
{
//2.1 设置边界值
int EndX=cols-1-start;
int EndY=rows-1-start;
//2.2 第一步从左到右打印
for(int i = start;i<=EndX;i++)
{
ret.push_back(matrix[start][i]);
}
//2.3 第二步从上到下打印 条件至少两行 start<EndY
if(start<EndY)
{
for(int i = start+1;i<=EndY;i++)
{
ret.push_back(matrix[i][EndX]);
}
}
//2.4第三步 从右往左 至少两列两行 start<EndX&&start<EndY
if(start<EndX&&start<EndY)
{
for(int i=EndX-1;i>=start;i--)
{
ret.push_back(matrix[EndY][i]);
}
}
//2.5第四步 从下往上 至少三行两列 start<EndX&&start<EndY-1
if(start<EndX&&start<EndY-1)
{
for(int i = EndY-1;i>start;i--)
{
ret.push_back(matrix[i][start]);
}
}
}
start++;
}
return ret;
Problem
1.How to set initial size of std::vector?
std::vector<CustomClass *> whatever(20000);or:
std::vector<CustomClass *> whatever;
whatever.reserve(20000);The former sets the actual size of the array -- i.e., makes it a vector of 20000 pointers.
The latter leaves the vector empty, but reserves space for 20000 pointers, so you can insert (up to) that many without it having to reallocate.
At least in my experience, it's fairly unusual for either of these to make a huge difference in performance--but either can affect correctness under some circumstances. In particular, as long as no reallocation takes place, iterators into the vector are guaranteed to remain valid, and once you've set the size/reserved space, you're guaranteed there won't be any reallocations as long as you don't increase the size beyond that.
2.Constructing vectors
// constructing vectors
#include <iostream>
#include <vector> int main ()
{
// constructors used in the same order as described above:
std::vector<int> first; // empty vector of ints
std::vector<int> second (4,100); // four ints with value 100
std::vector<int> third (second.begin(),second.end()); // iterating through second
std::vector<int> fourth (third); // a copy of third // the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29};
std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) ); std::cout << "The contents of fifth are:";
for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n'; return 0;
}Output:
The contents of fifth are: 16 2 77 29
3.Clearing vectors
清空容器中的内容,但如果是指针对象的话,并不能清空其内容,必须要像以下方法一样才能达到清空指针对象的内容:
vector<int*> xx;
for(int it=0;it!=xx.size();++it)
{
delete xx[it];
}
xx.clear();Removes all elements from the vector (which are destroyed), leaving the container with a size of 0.
A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. A typical alternative that forces a reallocation is to use swap:
vector<T>().swap(x); // clear x reallocating#include <iostream>
#include <vector> int main ()
{
std::vector<int> myvector;
myvector.push_back (100);
myvector.push_back (200);
myvector.push_back (300); std::cout << "myvector contains:";
for (unsigned i=0; i<myvector.size(); i++)
std::cout << ' ' << myvector[i];
std::cout << '\n'; myvector.clear();
myvector.push_back (1101);
myvector.push_back (2202); std::cout << "myvector contains:";
for (unsigned i=0; i<myvector.size(); i++)
std::cout << ' ' << myvector[i];
std::cout << '\n'; return 0;
}Output:
myvector contains: 100 200 300
myvector contains: 1101 220
4.《深入理解C++11》笔记--noexcept
5.reference binding to null pointer of type 'struct value_type'
在LeetCode做题的过程中,遇到"reference binding to null pointer of type ‘value_type’" 这个问题,现在对这个问题进行一下分析和总结。
产生原因:
1.对于一些stl和一些数据结构掌握不准确。
2.忽视判断条件。错误种类:
1.测试样例输入为非空数组情况:Runtime Error Message: reference binding to null pointer of type 'value_type' Last executed input: [1]
Runtime Error Message:reference binding to null pointer of type 'value_type' Last executed input:[[1,1,1],[1,0,1],[1,1,1]]
可能原因:
a.数组越界,在对vector初始化的时候没有初始化到合适大小,而在接下来的使用中使用了越界的下标。
例:class Solution {
public:
int maxProfit(vector<int>& nums) {
int len = prices.size();
vector<int> sold(len - 1, 0); // 初始化长度为len - 1
for (int i = 1; i < len; i++) {
sold[i] = 1; // 越界
}
return sold[len - 1]; // 访问越界
}
};b.对于vector构建出来的二维数组没有进行空间的申请,比如有些返回类型为vector<vector<>>类型的函数,对于这个返回值vector表示的二维数组要先申请大小,否则使用下标访问就会报这类错误。
例:vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
vector<vector<int>> res(M.size()); // 这里要进行初始化
for (int i = 0; i < res.size(); i++) res[i].resize(M[0].size()); // 这里也要进行初始化
for (int i = 0; i < M.size(); i++) {
for (int j = 0; j < M[0].size(); j++) {
res[i][j] = 1;
}
}
return res;
}2.测试样例输入为空数组情况:
Runtime Error Message:reference binding to null pointer of type 'value_type'
Last executed input:[]可能原因:
对于数组长度为0的情况没有进行判断,加入判断条件就可以解决。解决方法:函数入口判断,返回一个临时变量
vector<int> spiralOrder(vector<vector<int>>& matrix)
{
vector<int> temp;
if(!matrix.size())
return temp;
}
总结
这类错误多数是因为在编程的过程中由于一些判断或者初始化细节没有考虑到,解决起来很简单,但是也容易让人忽视。
5.位运算
总是把 * 2的操作 写成 <<2,实际上应该是 <<1
而且优先级见下 ,高于比较运算符,从左至右
第29题:LeetCode54:Spiral Matrix螺旋矩阵的更多相关文章
- Leetcode54. Spiral Matrix螺旋矩阵
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ...
- Leetcode 54:Spiral Matrix 螺旋矩阵
54:Spiral Matrix 螺旋矩阵 Given a matrix of m x n elements (m rows, n columns), return all elements of t ...
- [LeetCode] Spiral Matrix 螺旋矩阵
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...
- PAT甲级——1105 Spiral Matrix (螺旋矩阵)
此文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/90484058 1105 Spiral Matrix (25 分) ...
- leetCode 54.Spiral Matrix(螺旋矩阵) 解题思路和方法
Spiral Matrix Given a matrix of m x n elements (m rows, n columns), return all elements of the matri ...
- 【LeetCode每天一题】Spiral Matrix(螺旋打印数组)
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...
- [leetcode]54. Spiral Matrix螺旋矩阵
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...
- 【LeetCode】Spiral Matrix(螺旋矩阵)
这是LeetCode里的第54道题. 题目要求: 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ...
- spiral matrix 螺旋矩阵
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...
随机推荐
- jmeter beanshell Typed variable declaration : Object constructor错误
从数据库取值和响应值做比较,使用beanshell如下: import org.json.JSONArray; import org.json.JSONObject; res_str = prev.g ...
- 理解js继承的6种方式
想要继承,就必须要提供个父类(继承谁,提供继承的属性) 一.原型链继承 重点:让新实例的原型等于父类的实例. 特点:1.实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性.(新 ...
- ng2学习--pipe使用
We use our custom pipe the same way we use built-in pipes.(自定义Pipe和API里自带的Pipe使用方式一致) We must includ ...
- aspnetcore进程内托管的坑-非常规方法解决Log4Net不写日志的问题
问题描述:Log4Net,本地测试一切正常,发布后,无法自动创建文件夹和日志文件,无法写入文件. 一.在项目中配置Log4Net 请参考我的上一篇博客 <aspnetcore配置log4net并 ...
- Mysql与Sql server,Sum函数跟Count函数
两者均是统计类函数,都不计算NULL字段!!! 单纯计算行数的话,count的效率比sum的效率高 MySQL SUM()函数介绍 SUM()函数用于计算一组值或表达式的总和,SUM()函数的语法如下 ...
- HDU 4143 A Simple Problem 分解因式
求一个最小的正整数x,使得(y + x) (y - x) = n成立 考虑一下n的分解因式. 可能会想到枚举n的约数,那么a * b = n成立,取最小的x即可 但是要枚举到n / 2,这样会超时. ...
- ERROR [org.apache.hadoop.util.Shell] - Failed to locate the winutils binary in the hadoop binary path
错误日志如下: -- ::, DEBUG [org.apache.hadoop.metrics2.lib.MutableMetricsFactory] - field org.apache.hadoo ...
- Zookeeper问题汇总
1. 遗留问题 a). zookeeper集群如何保证请求的均匀分布? 2. ZK概念澄清 2.1 ZK节点类型 CreateMode.PERSISTENT //持久节点,该节点客户端断开后不会删除 ...
- discuz迁移到虚拟空间后无法上传图片的问题
discuz X3迁移到虚拟空间后无法上传图片,提示"附件无法保存": 解决方法: 1.看看虚拟空间的容量是不是满了. 2.登录管理员后台,工具->更新缓存.
- 在 Angularjs 中 ui-sref 和 $state.go 如何传递单个多个参数和将对象作为参数
一: 如何传递单个参数 首先,要在目标页面定义接受的参数: 传参, 接收参数, 在目标页面的controller里注入$stateParams,然后 "$stateParams.参数名&qu ...
