螺旋矩阵 - 中等

*************

C++

topic: 54. 螺旋矩阵 - 力扣(LeetCode)

*************

Look at the problem first.

Matrix is composed of n lines and n columns. Yesterday I learned how to creat one-dimension vector and two-dimension vector. And I am going to relearn again.

create one-dimension vector.

// 参数类型 参数名
vector<int> w;

// 直接传递参数
vector<int> w1 = {1, 2, 3, 4, 5};

// 构造参数
vector<int> w2(13, 38); // 13个元素,每个元素值为38

create two-dimension vector.

// 直接传递参数
vector<vector<int>> w3 = {{1, 2, 3}, {4, 5, 6}}; // 二维数组
// 构造参数
vector<vector<int>> w4(13, vector<int>(13, 38)); // 13行13列,每个元素值为38

Beside this, c++ allows you do something in vector library. Here are some basic usages I've meet in the topics.

// vector基础操作
vector<int> w(13, 0); 
// w = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 初始化为13个元素,每个元素值为0

// 末尾添加元素1
w.push_back(1); 
// w = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; // 添加元素1

// 末尾添加元素2
w.push_back(2);
// w = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2}; // 添加元素2

// 末尾删除元素2
w.pop_back();
// w = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; // 删除元素2

// 末尾删除元素1
w.pop_back();
// w = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 删除元素1

// 查看大小
int n = w.size();
// n = 13; // 大小为13

So need a coordinate axis system.

remember the last topic, matrix with directions? 

困于环中的机器人-优快云博客https://blog.youkuaiyun.com/ElseWhereR/article/details/146816399?spm=1001.2014.3001.5502

When looking at this topic, I tend to immediately refer the robot problem, which indicates the robot always turns right. Annotate that traverse the whole matrix is incrediblely crucial. So the return the reault and get the size is very cradible.

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        
        // 初始化一个vector,用来存储遍历的数字
        vector<int> result;

        // 获得矩阵大小
        int m = matrix.size(); // 有多少行
        int n = matrix[0].size(); // 有多少列
    }
};

I have a doubt that why matrix[0].size() means the number of columns? and soon I figure out that matrix[0] means the first line of the matrix. and matrix[0].size() means the numbers of elements that the first line contains.

Deal with the first line is really easy.

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        
        // 初始化一个vector,用来存储遍历的数字
        vector<int> result;

        // 获得矩阵大小
        int m = matrix.size(); // 有多少行
        int n = matrix[0].size(); // 有多少列

        for (int i = 0; i < m; i++)
        {
            result.push_back(matrix[0][i]);
        }
    }
};

and then turn right for the first time.

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        
        // 初始化一个vector,用来存储遍历的数字
        vector<int> result;

        // 获得矩阵大小
        int m = matrix.size(); // 有多少行
        int n = matrix[0].size(); // 有多少列

        for (int i = 0; i < m; i++)
        {
            result.push_back(matrix[0][i]);
        }

        // 第一次向右转
        for (int j = 0; j < n; j++)
        {
            result.push_back(matrix[j][m - 1]);
        }
    }
};

and turn right for the second time.

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        
        // 初始化一个vector,用来存储遍历的数字
        vector<int> result;

        // 获得矩阵大小
        int m = matrix.size(); // 有多少行
        int n = matrix[0].size(); // 有多少列

        for (int i = 0; i < m; i++)
        {
            result.push_back(matrix[0][i]);
        }

        // 第一次向右转
        for (int j = 0; j < n; j++)
        {
            result.push_back(matrix[j][m - 1]);
        }

        // 第二次程序转弯
        for (int i = n - 1; i >= 0; i--)
        {
            result.push_back(matrix[m - 1][i]);
        }
    }
};

You get it? Every three turnning around makes a loop. So define the top, bottom, left and right.

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        
        // 初始化一个vector,用来存储遍历的数字
        vector<int> result;

        // 获得矩阵大小
        int m = matrix.size(); // 有多少行
        int n = matrix[0].size(); // 有多少列

        // 规定循环的边界感
        int top = 0;
        int bottom = m - 1;
        int left = 0;
        int right = n - 1;

        // 开始进入loop
        while (top <= bottom && left <= right)
        {
            // do somethig here
        }

    }
};

 

// 从左到右遍历上边界
            for (int j = left; j <= right; ++j) {
                result.push_back(matrix[top][j]);
            }
            top++;

// 从上到下遍历右边界
            for (int i = top; i <= bottom; ++i) {
                result.push_back(matrix[i][right]);
            }
            right--;

  // 从右到左遍历下边界
            for (int j = right; j >= left; --j) {
                result.push_back(matrix[bottom][j]);
            }
            bottom--;

 // 从下到上遍历左边界
            for (int i = bottom; i >= top; --i) {
                result.push_back(matrix[i][left]);
            }
            left++;

here we go:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        
        // 初始化一个vector,用来存储遍历的数字
        vector<int> result;

        // 获得矩阵大小
        int m = matrix.size(); // 有多少行
        int n = matrix[0].size(); // 有多少列

        // 规定循环的边界感
        int top = 0;
        int bottom = m - 1;
        int left = 0;
        int right = n - 1;

        // 开始进入loop
        while (top <= bottom && left <= right)
        {
            // do somethig here

            // →
            for (int j = left; j <= right; j++)
            {
                result.push_back(matrix[top][j]);
            }
            top++;

            // ↓
            for (int i = top; i <= bottom; ++i) 
            {
                result.push_back(matrix[i][right]);
            }
            right--;

            // ←
            for (int j = right; j >= left; --j) 
            {
                result.push_back(matrix[bottom][j]);
            }
            bottom--;

            // ↑
            for (int i = bottom; i >= top; --i) 
            {
                result.push_back(matrix[i][left]);
            }
            left++;

        }

        return result;
    }
};

The program seems perfecct and why is wrong?

0123
01234
15678
29101112

When the program go to matrix[1][2], which is 7, 6 is redundent.

  • 在第二轮循环开始时,top=1,bottom=1,left=1,right=2。进入循环。
  • 向右:j从1到2,添加matrix[1][1]=6,matrix[1][2]=7 → result变为[1,2,3,4,8,12,11,10,9,5,6,7]。然后top++到2。
  • 向下:i从2到bottom=1 → 不执行,直接跳过。right减到1。
  • 向左:j从1到left=1 → j=1,添加matrix[bottom=1][1]=6 → result变为[…,6,7,6]。然后bottom–到0.
  • 向上:i从0到top=2 → 循环条件i >=2,不执行。left++到2.
  • 此时,top=2,bottom=0 → 条件top<=bottom不成立,退出循环。

things goes wrong.

add if (top > bottom) break;  if (left > right) break;

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        
        // 初始化一个vector,用来存储遍历的数字
        vector<int> result;

        // 获得矩阵大小
        int m = matrix.size(); // 有多少行
        int n = matrix[0].size(); // 有多少列

        // 规定循环的边界感
        int top = 0;
        int bottom = m - 1;
        int left = 0;
        int right = n - 1;

        // 开始进入loop
        while (top <= bottom && left <= right)
        {
            // do somethig here

            // →
            for (int j = left; j <= right; j++)
            {
                result.push_back(matrix[top][j]);
            }
            top++;

            // ↓
            for (int i = top; i <= bottom; ++i) 
            {
                result.push_back(matrix[i][right]);
            }
            right--;

            if (top > bottom)
            {
                break;
            }

            // ←
            for (int j = right; j >= left; --j) 
            {
                result.push_back(matrix[bottom][j]);
            }
            bottom--;

            if (left > right)
            {
                break;
            }

            // ↑
            for (int i = bottom; i >= top; --i) 
            {
                result.push_back(matrix[i][left]);
            }
            left++;

        }

        return result;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值