热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【ACM】顺时针打印矩阵

问题描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:12345678910111213141516则依次打

问题描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
例如,如果输入如下矩阵: 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.


算法描述:
以(x,y)元组作为当前打印元素的指针,当前位置加上-1,0,1分别
表示x,y坐标后退、保持不变和前进。如矩阵
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

若当前位置为(0,0),则打印1;
顺时针打印时,移动到下一个位置即x+1,y+0,故为(1,0),即打印2;
再往下,(2,0),打印3;
……
最后一个元素则是(1,2),打印10.
首先检测是否为单行单列,若是,则只需一个for循环即可解决,否则进入下一步:
从坐标(0,0)开始,x依次递增,y不变,同时,记录x,y的最大最小值x_min,x_max和y_min.y_max,然后开始移动坐标;
当移到边界位置(x_max,y_min)时,表明第一行已打印完,故x_min+=1,同时x将保持不变,y往下递增;
当移到边界位置(x_max,y_max)时,表明最后一列已打印完,故y_max-=1,同时y将保持不变,x往后递减;
当移到边界位置(x_min,y_max)时,表明最后一行已打印完,故x_max-=1,同时x将保持不变,y往上递减;
当移到边界位置(x_min,y_min)时,表明第一列已打印完,故y_min-=1,同时y将保持不变,x往前递增,需注意,这一步需是已经顺时针遍历一圈后才能进行检测。
在编码时,每次min和max的变化需移至下一个边界点的到来才能进行,否则会陷入死循环导致数组溢出(具体可看代码)。


代码如下:

class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        vector<int> results;
        if (matrix.size() == 0) {
            return results;
        }

        int x = 0; 
        int y = 0; //当前元素的位置

        int xf = 0;
        int yf = 1;//xf和yf表示当前元素位置指针的方向,-1表后退,0停止,1前进

        int rows = matrix.size()-1;     //行
        int cols = matrix.at(0).size()-1; //列
        //当只有一行时
        if (rows == 0) {
            for (int i = 0; i <= cols; i++) {
                results.push_back(matrix.at(0).at(i));
            }
            return results;
        }
        //当只有一列时
        if (cols == 0) {
            for (int i = 0; i <= rows; i++) {
                results.push_back(matrix.at(i).at(0));
            }
            return results;
        }

        int x_start = 0;
        int y_start = 0;

        int x_end = rows;
        int y_end = cols;

        bool isFirst = true;

        int size = (rows+1)*(cols+1);   //元素个数
        while (results.size() //记录当前元素
            x += xf;                            //横坐标变换
            y += yf;                            //纵坐标变化
            //开始进行四个角的判断以及相关操作
            if (x == x_start && y == y_end) {
                xf = 1;
                yf = 0;
                if (!isFirst) {
                    y_start += 1;
                }
            }
            if (x == x_end && y == y_end) {
                xf = 0;
                yf = -1;
                x_start += 1;

            }
            if (x == x_end && y == y_start) {
                xf = -1;
                yf = 0;
                y_end -= 1;

            }
            if (x == x_start && y == y_start) {
                xf = 0;
                yf = 1;
                x_end -= 1;
                isFirst = false;
            }
        }
        return results;
    }
};

测试代码:

int main() {

    vector<vector<int> > matrix;
    int x = 1;
    for (int i = 0; i <4; i++) {
        vector<int> tmp;
        for (int j = 0; j <1; j++) {
            tmp.push_back(x++);
        }
        matrix.push_back(tmp);
    }

    Solution s;

    vector<int> re = s.printMatrix(matrix);

    for (int i = 0; i cout <" ";
    }
}

推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
author-avatar
棋牌
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有