Code28 顺时针打印矩阵

题目

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

示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100

代码
  • 思路 递归
    • 每次获取一个 “口” 字形顺时针的数字;
    • 针对每个 “口” 字形,只需知道 起始点坐标(左上点) 以及 行数 和 列数 即可;
      • 起始点坐标,假设为(start_row, start_col)
      • 行数,假设为 row_len
      • 列数,假设为 col_len
    • 外层和内一层的 “口” 字形 关系为 起始点坐标均+1, 行数和列数均-2。
    • 需要注意最内层有几种不同情况:
      • “.” 字形, 例如 3*3 矩阵
      • “一” 字形, 例如 3*4 矩阵
      • “|” 字形, 例如 4*3 矩阵
      • “口” 字形, 例如 4*4 矩阵
  • 代码
#include <algorithm>
#include <vector>
using namespace std;
class Solution {
 public:
  vector<int> spiralOrder(vector<vector<int>>& matrix) {
    int row = matrix.size();
    if (0 == row) {
      return vector<int>();
    }

    int col = matrix[0].size();
    if (0 == col) {
      return vector<int>();
    }

    return getCircle(matrix, 0, 0, row, col);
  }

 private:
  vector<int> getCircle(vector<vector<int>>& matrix,
                        int start_row,
                        int start_col,
                        int row_len,
                        int col_len) {
    if (row_len < 1 || col_len < 1) {
      return vector<int>();
    }

    vector<int> res;

    if (1 == row_len && 1 == col_len) {
      // .
      res.push_back(matrix[start_row][start_col]);
    } else if (1 == row_len) {
      // ——
      for (int i = 0; i < col_len; ++i) {
        res.push_back(matrix[start_row][start_col + i]);
      }
    } else if (1 == col_len) {
      // |
      for (int i = 0; i < row_len; ++i) {
        res.push_back(matrix[start_row + i][start_col]);
      }
    } else {
      // 口
      for (int i = 0; i < col_len; ++i) {
        res.push_back(matrix[start_row][start_col + i]);
      }

      for (int i = 1; i < row_len; ++i) {
        res.push_back(matrix[start_row + i][start_col + col_len - 1]);
      }

      for (int i = col_len - 2; i >= 0; --i) {
        res.push_back(matrix[start_row + row_len - 1][start_col + i]);
      }

      for (int i = row_len - 2; i > 0; --i) {
        res.push_back(matrix[start_row + i][start_col]);
      }
    }

    auto inner_circle = getCircle(matrix, start_row + 1, start_col + 1,
                                  row_len - 2, col_len - 2);

    copy(inner_circle.begin(), inner_circle.end(), back_inserter(res));

    return res;
  }
};
测试
#include <iostream>
int main() {
   Solution s;
   {
     vector<vector<int>> matrix{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
     auto res = s.spiralOrder(matrix);
     for (auto i : res) {
       cout << i << " ";
     }
     cout << endl;
   }
   {
     vector<vector<int>> matrix{{3}, {2}};
     auto res = s.spiralOrder(matrix);
     for (auto i : res) {
       cout << i << " ";
     }
   }

  cin.get();
  return 0;
}
  • 结果
1 2 3 4 8 12 11 10 9 5 6 7
3 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值