【LeetCode】螺旋矩阵&&旋转图像

简介: 【LeetCode】螺旋矩阵&&旋转图像

👉螺旋矩阵👈


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


示例 1:

5134b73195354369aec0d999435ebac3.png

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

输出:[1,2,3,6,9,8,7,4,5]



示例 2:


ed2710207d784df5ac2efd45988c394a.png


输入: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]



提示:


m == matrix.length

n == matrix[i].length

1 <= m, n <= 10

-100 <= matrix[i][j] <= 100


思路:先分别定义上下左右边界cur、below、left和right,当上边界大于下边界或者左边界大于右边界时,退出while循环。循环开始,首先,利用for循环向右遍历矩阵,依次将矩阵的元素加入到返回的数组中。第一个for循环结束,cur++,调整上边界并判断是否大于下边界。如果大于下边界就退出while循环,否则向下遍历矩阵。遍历的方式以及while循环的条件类似,在此就不赘述了。


int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize)
{
    *returnSize = matrixSize * (*matrixColSize);//返回数组元素的个数
    int* ret = (int*)malloc(sizeof(int)*(*returnSize));
    int n = 0;//数组下标
    int cur = 0;//上边界
    int below = matrixSize - 1;//下边界
    int left = 0;//左边界
    int right = *matrixColSize - 1;//右边界
    int i = 0;
    while(1)
    {
        //向右遍历一行
        for(i = left; i <= right; i++)
        {
            ret[n++] = matrix[cur][i];
        }
        //调整上边界,若上边界大于下边界,则遍历矩阵完成
        cur++;
        if(cur > below) 
            break;
        //向下遍历一列
        for(i = cur; i <= below; i++)
        {
            ret[n++] = matrix[i][right];
        }
        //调整右边界,左边界大于右边界,则遍历矩阵完成
        right--;
        if(left > right)
            break;
        //向左遍历一行
        for(i = right; i >= left; i--)
        {
            ret[n++] = matrix[below][i];
        }
        //调整下边界,若上边界大于下边界,则遍历矩阵完成
        below--;
        if(cur > below)
            break;
        //向上遍历一列
        for(i = below; i >= cur; i--)
        {
            ret[n++] = matrix[i][left];
        }
        //调整左边界,左边界大于右边界,则遍历矩阵完成
        left++;
        if(left > right)
            break;
    }
    return ret;
}

ef332fd39a3048f9997750538e569975.png


👉螺旋矩阵II👈


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

示例 1:

输入:n = 3

输出:[[1,2,3],[8,9,4],[7,6,5]]


示例 2:

输入:n = 1

输出:[[1]]


提示:

1 <= n <= 20


思路:我们可以借助螺旋矩阵的遍历的方式,依次给矩阵赋值。


int** generateMatrix(int n, int* returnSize, int** returnColumnSizes)
{
    *returnSize = n;//函数
    *returnColumnSizes = (int*)malloc(sizeof(int)*n);//列数组
    int** ret = (int**)malloc(sizeof(int*)*n);
    int i = 0;
    for(i = 0; i < n; i++)
    {
        ret[i] = (int*)calloc(n, sizeof(int));//将矩阵中的元素初始化为0
        (*returnColumnSizes)[i] = n;//每一列元素的个数
    }
    int cur = 0;//上边界
    int left = 0;//左边界
    int right = n - 1;//右边界
    int below = n - 1;//下边界
    int count = 1;//元素
    while(1)
    {
        //向右遍历给矩阵赋值
        for(i = left; i <= right; i++)
        {
            ret[cur][i] = count;
            count++;
        }
        //调整上边界
        cur++;
        //判断上边界是否大于下边界,如果大于,赋值完成,退出循环
        if(cur > below)
            break;
        //向下遍历给矩阵赋值
        for(i = cur; i <= below; i++)
        {
            ret[i][right] = count;
            count++;
        }
        //调整右边界
        right--;
        //判断左边界是否大于右边界,如果大于,赋值完成,退出循环
        if(left > right)
            break;
        //向左遍历给矩阵赋值
        for(i = right; i >= left; i--)
        {
            ret[below][i] = count;
            count++;
        }
        //调整下边界
        below--;
        //判断上边界是否大于下边界,如果大于,赋值完成,退出循环
        if(cur > below)
            break;
        //向上遍历给矩阵赋值
        for(i = below; i >= cur; i--)
        {
            ret[i][left] = count;
            count++;
        }
        //调整左边界
        left++;
        //判断左边界是否大于右边界,如果大于,赋值完成,退出循环
        if(left > right)
            break;
    }
    return ret;
}

0f1f2609015e467393396b25da63a80d.png


👉旋转图像👈


给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。


你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:


1313813f7bfa4ddd84ea619d35e8c8d6.png

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

输出:[[7,4,1],[8,5,2],[9,6,3]]



示例2:

2f03328c0f4843719cd0372180ad789c.png


输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]

输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]



提示:


n == matrix.length == matrix[i].length

1 <= n <= 20

-1000 <= matrix[i][j] <= 1000


思路:先将矩阵中的元素上下对称交换,然后矩阵中的元素再关于对角线交换,就能达到将图像顺时针旋转 90 度的效果了。

386552de394b4530b638d1ac392ede25.png

//交换元素的值
void swap(int* a, int* b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
void rotate(int** matrix, int matrixSize, int* matrixColSize)
{
    int i = 0;
    int j = 0;
    //上下交换
    for(i = 0; i < matrixSize / 2; i++)
    {
        for(j = 0; j < *matrixColSize; j++)
        {
            swap(&matrix[i][j], &matrix[matrixSize - 1 - i][j]);
        }
    }
    //对角线交换
    for(i = 0; i < matrixSize; i++)
    {
        for(j = 0; j < i; j++)
        {
            swap(&matrix[i][j], &matrix[j][i]);
        }
    }
}

331366e8909a49fdb9912a315ba2583f.png


👉总结👈


本篇文章主要讲解了挺经典的矩阵题目,尤其是旋转矩阵,对循环的把控需要掌握得很到位,才可能解得出来。可能这两道题目还有更加简便的解法,现在还未掌握,以后会加以补充。如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家啦!💖💝❣️

相关文章
【bug记录】旋转链表与力扣报错:member access within null pointer of type ‘struct ListNode‘
【bug记录】旋转链表与力扣报错:member access within null pointer of type ‘struct ListNode‘
205 0
|
11月前
|
C++
Leetcode第54题(螺旋矩阵)
这篇文章介绍了LeetCode第54题“螺旋矩阵”的解题思路和C++的实现代码,该题目要求按照顺时针螺旋顺序返回给定矩阵中的所有元素。
123 1
Leetcode第54题(螺旋矩阵)
|
11月前
|
机器学习/深度学习
Leetcode第48题(旋转图像)
这篇文章介绍了LeetCode第48题“旋转图像”的解题方法,通过原地修改二维矩阵实现图像的顺时针旋转90度。
93 0
Leetcode第48题(旋转图像)
|
11月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
93 0
Leetcode第三十三题(搜索旋转排序数组)
|
11月前
【LeetCode 05】螺旋矩阵II总结
【LeetCode 05】螺旋矩阵II总结
101 0
LeetCode第59题螺旋矩阵 II
LeetCode第59题"螺旋矩阵 II"的解题方法,通过模拟螺旋填充过程,一圈一圈从外到内按顺序填充数字,直到完成整个矩阵的构建。
LeetCode第59题螺旋矩阵 II
|
存储 算法
LeetCode第54题螺旋矩阵
LeetCode第54题"螺旋矩阵"的解题方法,通过模拟从外到内的螺旋遍历过程,并利用方向向量控制遍历方向的转换,有效输出矩阵的螺旋顺序。
LeetCode第54题螺旋矩阵
|
存储 算法
LeetCode第48题旋转图像
LeetCode第48题"旋转图像"的解题方法,通过两次翻转操作——先水平翻转再对角线翻转,实现了原地旋转矩阵的效果。
LeetCode第48题旋转图像
|
Python
【Leetcode刷题Python】剑指 Offer 11. 旋转数组的最小数字
解决剑指Offer 11题 "旋转数组的最小数字" 的三种Python实现方法:直接使用min函数、线性查找分界点和二分查找法,以找出旋转数组中的最小元素。
130 2
|
机器学习/深度学习 存储
力扣经典150题第三十六题:旋转图像
力扣经典150题第三十六题:旋转图像
102 0