精选算法题(2)——矩阵螺旋输出

简介: 精选算法题(2)——矩阵螺旋输出

题目描述:

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。


例如,如果输入4*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。


解题思路:

本题为了将矩阵顺时针螺旋输出。如下图所示,对每一圈而言,就是先获取第一行,再拿到最后一列,再拿最后一行,最后拿第一列,确定好对应的位置关系,用4个循环即可实现。考虑到可能会碰上行列不一致的情况,所以圈数要取行数和列数最小值的一半。另外,我发现当矩阵为3行4列时,第2圈只有6和7,此时用常规代码会将6重复获取两次,为了避免该情况发生,用mask作为数据是否获取的位置标识。

测试代码:

#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define min(a,b) (a < b ? a : b)
vector<int> getSpiralData(vector<vector<int>> inputs);
int main()
{
  // 输入矩阵
  vector<vector<int>> inputs = {
    {1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16},{17,18,19,20},{21,22,23,24}
  };
  // 输出输入
  cout << "输入:" << endl;
  for (int i = 0; i < inputs.size(); ++i)
  {
    for (int j = 0; j < inputs[0].size(); ++j)
    {
      cout << inputs[i][j] << " ";
    }
    cout << endl;
  }
  // 输出螺旋矩阵
  vector<int> output = getSpiralData(inputs);
  // 输出结果
  cout << "输出:" << endl;
  for (int i = 0; i < output.size(); ++i)
  {
    cout << output[i] << " ";
  }
  cout << endl;
  system("pause");
  return 0;
}
// 输出螺旋矩阵
vector<int> getSpiralData(vector<vector<int>> inputs)
{
  // 定义行列数
  int row = inputs.size();
  int col = inputs[0].size();
  // 定义起始点
  int startr = 0;
  int startc = 0;
  // 定义圈数,offset=0为第一圈
  int offset = 0;
  // 初始化输出
  vector<int> outputs;
  // 初始化掩膜,用来避免数据重复存储
  vector<vector<bool>> mask(row,vector<bool>(col,false));
  // 当行列不一致时,取最小值/2作为圈数
  int turns = (min(row, col) + 1 ) / 2;
  // 单圈存储
  while (turns)
  {
    int i = startr;
    int j = startc;
    // 顺时针第一行
    for (j = startc; j < col - offset; j++)
    {
      if (!mask[i][j])
      {
        outputs.push_back(inputs[i][j]);
        mask[i][j] = true;
      }
    }
    j--;
    // 顺时针最后一列
    for (i = startr + 1; i < row - offset; i++)
    {
      if (!mask[i][j])
      {
        outputs.push_back(inputs[i][j]);
        mask[i][j] = true;
      }
    }
    i--;
    // 顺时针最后一行
    for (j = col - offset - 2; j >= startc; j--)
    {
      if (!mask[i][j])
      {
        outputs.push_back(inputs[i][j]);
        mask[i][j] = true;
      }
    }
    j++;
    // 顺时针第一列
    for (i = row - offset - 2; i > startr; i--)
    {
      if (!mask[i][j])
      {
        outputs.push_back(inputs[i][j]);
        mask[i][j] = true;
      }
    }
    i++;
    // 圈数步进,下一圈的初始点的x和y值均+1
    offset++;
    startr++;
    startc++;
    turns--;
  }
  return outputs;
}

测试结果:

图1 4*4矩阵结果

图2 6*4矩阵结果

      如图1所示,4*4的矩阵按顺时针顺利获取,如图2所示6*4的矩阵也能按顺时针顺利获取。感兴趣的可以用3*4行试试,如果不用mask进行判断,得到的结果如图3所示,最后的6是重复的,这是因为第三个循环中j>=startc导致,但是这个等号也是很有必要的,为此加上mask即可解决该麻烦,正确结果如图4所示。

图3 错误的数据

图4 正确的数据

      如果代码有什么需要改进的或者有什么bug,欢迎评论留言,我会及时更正以免误导他人~

      如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章
|
7月前
|
算法 测试技术 C++
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
|
7月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-48 算法训练 关联矩阵
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-48 算法训练 关联矩阵
70 0
|
7月前
|
算法 测试技术 C#
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
【动态规划】【矩阵快速幂】【滚动向量】C++算法552. 学生出勤记录 II
|
2月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
机器学习/深度学习 算法 搜索推荐
django调用矩阵分解推荐算法模型做推荐系统
django调用矩阵分解推荐算法模型做推荐系统
44 4
|
2月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
164 0
|
4月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
57 6
|
7月前
|
算法 测试技术 编译器
【算法 | 实验18】在字符矩阵中查找给定字符串的所有匹配项
题目描述 题目 在字符矩阵中查找给定字符串的所有匹配项 给定一个M×N字符矩阵,以及一个字符串S,找到在矩阵中所有可能的连续字符组成的S的次数。所谓的连续字符,是指一个字符可以和位于其上下左右,左上左下,右上右下8个方向的字符组成字符串。用回溯法求解。
116 1
|
6月前
|
机器学习/深度学习 数据采集 人工智能
算法金 | 协方差、方差、标准差、协方差矩阵
**摘要:** 本文介绍了统计学中的基础概念,包括方差、标准差、协方差及其矩阵。方差衡量数据的分散程度,标准差是方差的平方根,提供相同单位下的波动度量。协方差则分析两个变量的关联性,正负值表示正负相关。协方差矩阵扩展到多变量情况,展示多个变量间的关系。这些工具在金融、质量控制、机器学习等领域有广泛应用。文章通过实例和公式清晰解释了每个概念,并强调理解它们之间的关系对于数据分析和统计建模的重要性。
82 0
算法金 | 协方差、方差、标准差、协方差矩阵
|
6月前
|
存储 算法 数据挖掘
python5种算法模拟螺旋、分层填充、递归、迭代、分治实现螺旋矩阵ll【力扣题59】
python5种算法模拟螺旋、分层填充、递归、迭代、分治实现螺旋矩阵ll【力扣题59】