📜  将矩阵的每个环逆时针旋转 K 个元素

📅  最后修改于: 2022-05-13 01:57:23.630000             🧑  作者: Mango

将矩阵的每个环逆时针旋转 K 个元素

给定一个 M*N 阶矩阵和一个值 K,任务是将矩阵的每个环逆时针旋转 K 个元素。如果在任何环元素中小于等于 K,则不要旋转它。
例子:

Input : k = 3
        mat[4][4] = {{1, 2, 3, 4},
                    {5, 6, 7, 8},
                    {9, 10, 11, 12},
                    {13, 14, 15, 16}}
Output: 4 8  12 16
        3 10  6 15
        2 11  7 14
        1  5  9 13

Input : k = 2
        mat[3][4] = {{1, 2, 3, 4},
                    {10, 11, 12, 5},
                    {9, 8, 7, 6}}
Output: 3 4  5  6
        2 11 12 7
        1 10  9 8

这个想法是以螺旋形式遍历矩阵。这是解决这个问题的算法:

  • 创建一个大小为 M*N 的辅助数组temp[]
  • 以螺旋形式开始遍历矩阵并将当前环的元素存储在 temp[] 数组中。在将元素存储在 temp 中时,跟踪当前环的开始和结束位置。
  • 对于存储在 temp[] 中的每个环,旋转该子数组 temp[]
  • 对矩阵的每个环重复此过程。
  • 在最后一次遍历矩阵中再次螺旋并将 temp[] 数组的元素复制到矩阵。

以下是上述步骤的 C++ 实现。

CPP
// C++ program to rotate individual rings by k in
// spiral order traversal.
#include
#define MAX 100
using namespace std;
 
// Fills temp array into mat[][] using spiral order
// traversal.
void fillSpiral(int mat[][MAX], int m, int n, int temp[])
{
    int i, k = 0, l = 0;
 
    /*  k - starting row index
        m - ending row index
        l - starting column index
        n - ending column index  */
    int tIdx  = 0;  // Index in temp array
    while (k < m && l < n)
    {
        /* first row from the remaining rows */
        for (int i = l; i < n; ++i)
            mat[k][i] = temp[tIdx++];
        k++;
 
        /* last column from the remaining columns */
        for (int i = k; i < m; ++i)
            mat[i][n-1] = temp[tIdx++];
        n--;
 
        /* last row from the remaining rows */
        if (k < m)
        {
            for (int i = n-1; i >= l; --i)
                mat[m-1][i] = temp[tIdx++];
            m--;
        }
 
        /* first column from the remaining columns */
        if (l < n)
        {
            for (int i = m-1; i >= k; --i)
                mat[i][l] = temp[tIdx++];
            l++;
        }
    }
}
 
// Function to spirally traverse matrix and
// rotate each ring of matrix by K elements
// mat[][] --> matrix of elements
// M     --> number of rows
// N    --> number of columns
void spiralRotate(int mat[][MAX], int M, int N, int k)
{
    // Create a temporary array to store the result
    int temp[M*N];
 
    /*      s - starting row index
            m - ending row index
            l - starting column index
            n - ending column index;  */
    int m = M, n = N, s = 0, l = 0;
 
    int *start = temp;  // Start position of current ring
    int tIdx = 0;  // Index in temp
    while (s < m && l < n)
    {
        // Initialize end position of current ring
        int *end = start;
 
        // copy the first row from the remaining rows
        for (int i = l; i < n; ++i)
        {
            temp[tIdx++] = mat[s][i];
            end++;
        }
        s++;
 
        // copy the last column from the remaining columns
        for (int i = s; i < m; ++i)
        {
            temp[tIdx++] = mat[i][n-1];
            end++;
        }
        n--;
 
        // copy the last row from the remaining rows
        if (s < m)
        {
            for (int i = n-1; i >= l; --i)
            {
                temp[tIdx++] = mat[m-1][i];
                end++;
            }
            m--;
        }
 
        /* copy the first column from the remaining columns */
        if (l < n)
        {
            for (int i = m-1; i >= s; --i)
            {
                temp[tIdx++] = mat[i][l];
                end++;
            }
            l++;
        }
 
        // if elements in current ring greater than
        // k then rotate elements of current ring
        if (end-start > k)
        {
            // Rotate current ring using reversal
            // algorithm for rotation
            reverse(start, start+k);
            reverse(start+k, end);
            reverse(start, end);
 
            // Reset start for next ring
            start = end;
        }
        else // There are less than k elements in ring
            break;
    }
 
    // Fill temp array in original matrix.
    fillSpiral(mat, M, N, temp);
}
 
// Driver program to run the case
int main()
{
    // Your C++ Code
    int M = 4, N = 4, k = 3;
    int mat[][MAX]= {{1, 2, 3, 4},
                     {5, 6, 7, 8},
                     {9, 10, 11, 12},
                     {13, 14, 15, 16} };
 
    spiralRotate(mat, M, N, k);
 
    // print modified matrix
    for (int i=0; i


输出:

4 8  12 16
3 10  6 15
2 11  7 14
1  5  9 13