【算法题】螺旋矩阵 I II III IV

这篇具有很好参考价值的文章主要介绍了【算法题】螺旋矩阵 I II III IV。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. 螺旋矩阵

2. 螺旋矩阵 II

3. 螺旋矩阵 III

4. 螺旋矩阵 IV


1. 螺旋矩阵

题目描述:

给你一个m行n列的矩阵matrix,请按照顺时针螺旋顺序 ,返回矩阵中的所有元素。

螺旋矩阵算法,算法题,算法

螺旋矩阵算法,算法题,算法

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

题解:

4×5的矩阵按顺时针螺旋顺序打印如图所示。

螺旋矩阵算法,算法题,算法

  • 每次从左往右走,都是从left走向right,结束后up++

螺旋矩阵算法,算法题,算法

  • 每次从上往下走,都是从up走向down,结束后right--

螺旋矩阵算法,算法题,算法

  • 每次从右往左走,都是从right走向left,结束后down--

螺旋矩阵算法,算法题,算法

  • 每次从下往上走,都是从down走向up,结束后left++

螺旋矩阵算法,算法题,算法

所以,螺旋矩阵每次循环分为4步;左→右、上→下、右→左、下→上,直到up>down或left>right跳出循环。

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> ans;

        int m = matrix.size();    // 行
        int n = matrix[0].size(); // 列

        int up = 0;        // 上边界
        int down = m - 1;  // 下边界
        int left = 0;      // 左边界
        int right = n - 1; // 右边界

        while (1)
        {
            // 左→右
            for (int j = left; j <= right; j++)
            {
                ans.push_back(matrix[up][j]);
            }
            if (++up > down)
            {
                break;
            }

            // 上→下
            for (int i = up; i <= down; i++)
            {
                ans.push_back(matrix[i][right]);
            }
            if (--right < left)
            {
                break;
            }

            // 右→左
            for (int j = right; j >= left; j--)
            {
                ans.push_back(matrix[down][j]);
            }
            if (--down < up)
            {
                break;
            }

            // 下→上
            for (int i = down; i >= up; i--)
            {
                ans.push_back(matrix[i][left]);
            }
            if (++left > right)
            {
                break;
            }
        }

        return ans;
    }
};

测试:

int main()
{
    vector<vector<int>> matrix = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20} };
    vector<int> v = Solution().spiralOrder(matrix);
    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;
    return 0;
}

螺旋矩阵算法,算法题,算法

2. 螺旋矩阵 II

题目描述:

给你一个正整数n,生成一个包含1到n^2所有元素,且元素按顺时针顺序螺旋排列的n x n正方形矩阵matrix。

螺旋矩阵算法,算法题,算法

提示:

  • 1 <= n <= 20

题解:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> ans(n, vector<int>(n)); // n*n的二维数组

        int up = 0;        // 上边界
        int down = n - 1;  // 下边界
        int left = 0;      // 左边界
        int right = n - 1; // 右边界
        int num = 1;       // 顺时针递增的矩阵元素

        while (1)
        {
            // 左→右
            for (int j = left; j <= right; j++)
            {
                ans[up][j] = num++;
            }
            if (++up > down)
            {
                break;
            }

            // 上→下
            for (int i = up; i <= down; i++)
            {
                ans[i][right] = num++;
            }
            if (--right < left)
            {
                break;
            }

            // 右→左
            for (int j = right; j >= left; j--)
            { 
                ans[down][j] = num++;
            }
            if (--down < up)
            {
                break;
            }

            // 下→上
            for (int i = down; i >= up; i--)
            {
                ans[i][left] = num++;
            }
            if (++left > right)
            {
                break;
            }
        }

        return ans;
    }
};

测试:

int main()
{
    vector<vector<int>> v = Solution().generateMatrix(10);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            printf("%3d ", v[i][j]);
        }
        printf("\n");
    }
    return 0;
}

螺旋矩阵算法,算法题,算法

3. 螺旋矩阵 III

题目描述:

在rows x cols的网格上,你从单元格 (rStart, cStart) 面朝东面开始。网格的西北角位于第一行第一列,网格的东南角位于最后一行最后一列。

你需要以顺时针按螺旋状行走,访问此网格中的每个位置。每当移动到网格的边界之外时,需要继续在网格之外行走(但稍后可能会返回到网格边界)。

最终,我们到过网格的所有rows x cols个空间。

按照访问顺序返回表示网格位置的坐标列表。

螺旋矩阵算法,算法题,算法

提示:

  • 1 <= rows, cols <= 100
  • 0 <= rStart < rows
  • 0 <= cStart < cols

题解:

以下图矩阵为例:

螺旋矩阵算法,算法题,算法

假设初始坐标为(rStart, cStart),上边界为rStart-1,下边界为rStart+1,左边界为cStart-1,右边界为Start+1。

假设当前坐标为(x, y)。

  • 每次从左往右走,都是从(x, y+1)走向(x, right),结束后right++

螺旋矩阵算法,算法题,算法

螺旋矩阵算法,算法题,算法

  • 每次从上往下走,都是从(x+1, y)走向(down, y),结束后down++

螺旋矩阵算法,算法题,算法

螺旋矩阵算法,算法题,算法

  • 每次从右往左走,都是从(x, y-1)走向(x, left),结束后left--

螺旋矩阵算法,算法题,算法

螺旋矩阵算法,算法题,算法

  • 每次从下往上走,都是从(x-1, y)走向(up, y),结束后up--

螺旋矩阵算法,算法题,算法

螺旋矩阵算法,算法题,算法

重复循环左→右、上→下、右→左、下→上,当答案数组的元素个数==网格面积时,表示已遍历完网格的全部元素。

class Solution {
public:
    vector<vector<int>> spiralMatrixIII(int rows, int cols, int rStart, int cStart) {
        vector<vector<int>> ans{ { rStart,cStart } }; // 先把起点存入答案数组
        int count = 1; // 表示答案数组的元素个数

        int up = rStart - 1;    // 上边界
        int down = rStart + 1;  // 下边界
        int left = cStart - 1;  // 左边界
        int right = cStart + 1; // 右边界

        int x = rStart; // 当前位置横坐标
        int y = cStart; // 当前位置纵坐标

        int area = rows * cols; // 网格面积,即所有元素的个数
        if (area == 1)
        {
            return ans;
        }

        while (1)
        {
            // 左→右
            for (int j = y + 1; j <= right; j++)
            {
                // 检查坐标是否在网格中
                if (x >= 0 && x < rows && j >= 0 && j < cols)
                {
                    ans.push_back({ x,j });
                    if (++count == area)
                    {
                        return ans;
                    }
                }
            }
            y = right; // 更新当前位置纵坐标
            right++;

            // 上→下
            for (int i = x + 1; i <= down; i++)
            {
                // 检查坐标是否在网格中
                if (i >= 0 && i < rows && y >= 0 && y < cols)
                {
                    ans.push_back({ i,y });
                    if (++count == area)
                    {
                        return ans;
                    }
                }
            }
            x = down; // 更新当前位置横坐标
            down++;

            // 右→左
            for (int j = y - 1; j >= left; j--)
            {
                // 检查坐标是否在网格中
                if (x >= 0 && x < rows && j >= 0 && j < cols)
                {
                    ans.push_back({ x,j });
                    if (++count == area)
                    {
                        return ans;
                    }
                }
            }
            y = left; // 更新当前位置纵坐标
            left--;

            // 下→上
            for (int i = x - 1; i >= up; i--)
            {
                // 检查坐标是否在网格中
                if (i >= 0 && i < rows && y >= 0 && y < cols)
                {
                    ans.push_back({ i,y });
                    if (++count == area)
                    {
                        return ans;
                    }
                }
            }
            x = up; // 更新当前位置横坐标
            up--;
        }
    }
};

测试:

int main()
{
    vector<vector<int>> v = Solution().spiralMatrixIII(4, 5, 1, 3);
    for (int i = 0; i < v.size(); i++)
    {
        for (int j = 0; j < v[0].size(); j++)
        {
            cout << v[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

螺旋矩阵算法,算法题,算法

4. 螺旋矩阵 IV

题目描述:

给你两个整数:m和n,表示矩阵的维数。

另给你一个整数链表的头节点head。

请你生成一个大小为m x n的螺旋矩阵,矩阵包含链表中的所有整数。链表中的整数从矩阵左上角开始、顺时针按螺旋顺序填充。如果还存在剩余的空格,则用-1填充。

返回生成的矩阵。

螺旋矩阵算法,算法题,算法

提示:

  • 1 <= m, n <= 105
  • 1 <= m * n <= 105
  • 链表中节点数目在范围[1, m * n] 内
  • 0 <= Node.val <= 1000

题解:

class Solution {
public:
    vector<vector<int>> spiralMatrix(int m, int n, ListNode* head) {
        vector<vector<int>> ans(m, vector<int>(n, -1)); // m*n的二维数组,全部初始化为-1

        int up = 0;        // 上边界
        int down = m - 1;  // 下边界
        int left = 0;      // 左边界
        int right = n - 1; // 右边界

        ListNode* cur = head;

        while (1)
        {
            // 左→右
            for (int j = left; j <= right; j++)
            {
                if (cur == nullptr)
                {
                    return ans;
                }
                ans[up][j] = cur->val;
                cur = cur->next;
            }
            if (++up > down)
            {
                break;
            }

            // 上→下
            for (int i = up; i <= down; i++)
            {
                if (cur == nullptr)
                {
                    return ans;
                }
                ans[i][right] = cur->val;
                cur = cur->next;
            }
            if (--right < left)
            {
                break;
            }

            // 右→左
            for (int j = right; j >= left; j--)
            { 
                if (cur == nullptr)
                {
                    return ans;
                }
                ans[down][j] =  cur->val;
                cur = cur->next;
            }
            if (--down < up)
            {
                break;
            }

            // 下→上
            for (int i = down; i >= up; i--)
            {
                if (cur == nullptr)
                {
                    return ans;
                }
                ans[i][left] = cur->val;
                cur = cur->next;
            }
            if (++left > right)
            {
                break;
            }
        }

        return ans;
    }
};

测试:

int main()
{
    ListNode* preHead = new ListNode;
    ListNode* tail = preHead;
    for (int i = 3; i <= 15; i++)
    {
        ListNode* newNode = new ListNode(i);
        tail->next = newNode;
        tail = tail->next;
    }

    vector<vector<int>> v = Solution().spiralMatrix(3, 5, preHead->next);
    for (int i = 0; i < v.size(); i++)
    {
        for (int j = 0; j < v[0].size(); j++)
        {
            printf("%2d ", v[i][j]);
        }
        printf("\n");
    }

    return 0;
}

螺旋矩阵算法,算法题,算法文章来源地址https://www.toymoban.com/news/detail-616142.html

到了这里,关于【算法题】螺旋矩阵 I II III IV的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法训练 Day 2 | 数组:977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II

    977. 有序数组的平方 第一想法:暴力破解 看完题解想法:朝着双指针方向想 遇到困难: 用双指针的话,一开始想到两边指针往中间靠,逐个将最大值赋给结果数组。和题解不同的是,循环条件我写了  while (left != right) {...} ,相比于题解的  while (left = right) {...} ,我需要在后

    2023年04月12日
    浏览(37)
  • 螺旋矩阵 II——力扣59

    题目描述 法一 模拟 初始化一个二维向量,名为matrix,它有n行和n列。向量的每个元素都是一个整数,初始化为0。初始化二维向量的语法如下: vectorvectorint matrix(n, vectorint(n)); 。 第一个参数n指定矩阵的行数 , 第二个参数vector(n)指定矩阵的列数 。第二个参数创建了一个大小

    2024年02月14日
    浏览(25)
  • Leecode螺旋矩阵 II59

     59.螺旋矩阵II 题目建议:  本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义,在这里又用上了。  题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 文章讲解:代码随想录 视频讲解:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili 2023/08/

    2024年02月13日
    浏览(22)
  • LeetCode59 螺旋矩阵 II

    螺旋矩阵 II 循环不变量的应用 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1: 输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]] 示例 2: 输入:n = 1 输出:[[1]] 提示: 1 = n = 20

    2024年01月23日
    浏览(30)
  • LeetCode 59. 螺旋矩阵 II

    题目链接:LeetCode 59. 螺旋矩阵 II 本题不涉及算法,只是简单的模拟,但是由于边界条件比较多,因此容易出错。 分析题干:题目要求按照右、下、左、上、这样的顺序对数组进行填充,填充的值为 1 ~ n*n ,因此问题的关键就是找到待填充的位置,将其值赋值为 i 即可。 由于

    2024年02月02日
    浏览(29)
  • 【LeetCode-中等题】59. 螺旋矩阵 II

    定义四个边界条件,每转一圈,把数值填进去,然后缩小一圈,直到不满足条件位置 结束循环条件可以是: 两种结束条件都可以,但是一定要注意每次处理一条边界的范围 不能重复赋值

    2024年02月09日
    浏览(31)
  • 算法练习Day50|● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

    LeetCode:123.买卖股票的最佳时机III 123. 买卖股票的最佳时机 III - 力扣(LeetCode) 1.思路 将两次买入卖出转化为是否持有的状态,当天可进行两次买卖,故每天买卖有四种状态,四种状态包含了当天不买不卖的状态。 2.代码实现 3.复杂度分析 时间复杂度:O(n). 空间复杂度:O(1

    2024年02月12日
    浏览(33)
  • 算法训练第五十天 | 123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

    题目链接:123.买卖股票的最佳时机III 参考:https://programmercarl.com/0123.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAIII.html 视频讲解:https://www.bilibili.com/video/BV1WG411K7AR 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所

    2024年02月01日
    浏览(29)
  • java算法day50 | ● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

    思路: 这道题的关键就是如何设置dp数组的状态。用五种状态表示对股票持有或售出的不同阶段。代码随想录讲解视频 时间复杂度:O(n) 空间复杂度:O(n × 5) 思路: 在上一题2次的基础上变为k次。可以发现规律:除了0以外,偶数就是卖出,奇数就是买入。 因此dp数组的维度

    2024年04月11日
    浏览(32)
  • 有序数组的平方 长度最小的子数组 螺旋矩阵II

    977. 有序数组的平方 - 力扣(LeetCode) 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100] 示例

    2024年02月12日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包