📜  使用 O(1) 额外空间打印 nxn 螺旋矩阵

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

使用 O(1) 额外空间打印 nxn 螺旋矩阵

给定一个数字 n,使用 O(1) 空间以顺时针方向打印 anxn 螺旋矩阵(数字从 1 到 nxn)。

例子 :

Input: n = 5
Output:
25 24 23 22 21
10  9  8  7 20
11  2  1  6 19
12  3  4  5 18
13 14 15 16 17

我们强烈建议您最小化您的浏览器并首先自己尝试。
如果允许额外的空间,解决方案就变得简单了。我们为 nxn 矩阵分配内存,对于从 n*n 到 1 的每个元素,我们开始以螺旋顺序填充矩阵。为了保持螺旋顺序,使用了四个循环,每个循环用于矩阵的顶部、右侧、底部和左侧角。

但是如何在 O(1) 空间中解决它呢?
一个 nxn 矩阵具有 ceil(n/2) 个平方周期。一个循环由第 i 行、第 (n-i+1) 列、第 (n-i+1) 行和第 i 列形成,其中 i 从 1 变化到 ceil(n/2)。

25 24 23 22 21 
10 9  8  7  20
11 2  1  6  19
12 3  4  5  18
13 14 15 16 17
  1. 第一个循环由它的第一行、最后一列、最后一行和第一列的元素组成(用红色标记)。第一个循环由从 n*n 到 (n-2)*(n-2) + 1 的元素组成。即从 25 到 10。
  2. 第二个循环由第二行、倒数第二列、倒数第二行和第二列的元素组成(用蓝色标记)。第二个循环由 (n-2)*(n-2) 到 (n-4)*(n-4) + 1 的元素组成。即从 9 到 2。
  3. 第三个循环由第三行、倒数第三列、倒数第三行和第三列的元素组成(用黑色标记)。第三个循环由 (n-4)*(n-4) 到 1 的元素组成。即只有 1。

这个想法是对于每个方形循环,我们将一个标记与其关联。对于外循环,标记的值为 0,对于第二个循环,它的值为 1,对于第三个循环,它的值为 2。通常对于 anxn 矩阵,第 i 个循环的标记值为 i-1。
如果我们将矩阵分成两部分,右上三角形(标记为橙色)和左下三角形(标记为绿色),然后使用标记 x,我们可以轻松计算将出现在索引处的值(i,j ) 在任何 nxn 螺旋矩阵中使用以下公式 -

25  24 23 22 21 
10  9  8  7  20 
11  2  1  6  19 
12  3  4  5  18 
13  14 15 16 17 
For upper right half,
mat[i][j] = (n-2*x)*(n-2*x)-(i-x)-(j-x)

For lower left half,
mat[i][j] = (n-2*x-2)*(n-2*x-2) + (i-x) + (j-x)

下面是这个想法的实现。

C++
// C++ program to print a n x n spiral matrix
// in clockwise direction using O(1) space
#include 
using namespace std;
 
// Prints spiral matrix of size n x n containing
// numbers from 1 to n x n
void printSpiral(int n)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            // x stores the layer in which (i, j)th
            // element lies
            int x;
 
            // Finds minimum of four inputs
            x = min(min(i, j), min(n-1-i, n-1-j));
 
            // For upper right half
            if (i <= j)
                printf("%d\t ", (n-2*x)*(n-2*x) - (i-x)
                    - (j-x));
 
            // for lower left half
            else
                printf("%d\t ", (n-2*x-2)*(n-2*x-2) + (i-x)
                    + (j-x));
        }
        printf("\n");
    }
}
 
// Driver code
int main()
{
    int n = 5;
 
    // print a n x n spiral matrix in O(1) space
    printSpiral(n);
 
    return 0;
}


Java
// Java program to print a n x n spiral matrix
// in clockwise direction using O(1) space
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Prints spiral matrix of size n x n
    // containing numbers from 1 to n x n
    static void printSpiral(int n)
    {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                 
                // x stores the layer in which (i, j)th
                // element lies
                int x;
 
                // Finds minimum of four inputs
                x = Math.min(Math.min(i, j),
                    Math.min(n - 1 - i, n - 1 - j));
 
                // For upper right half
                if (i <= j)
                    System.out.print((n - 2 * x) * (n - 2 * x) -
                                     (i - x) - (j - x) + "\t");
 
                // for lower left half
                else
                    System.out.print((n - 2 * x - 2) * (n - 2 * x - 2) +
                                     (i - x) + (j - x) + "\t");
            }
            System.out.println();
        }
    }
 
    // Driver code
    public static void main(String args[])
    {
        int n = 5;
 
        // print a n x n spiral matrix in O(1) space
        printSpiral(n);
    }
}
 
/*This code is contributed by Nikita Tiwari.*/


Python3
# Python3 program to print a n x n spiral matrix
# in clockwise direction using O(1) space
 
# Prints spiral matrix of size n x n
# containing numbers from 1 to n x n
def printSpiral(n) :
     
    for i in range(0, n) :
        for j in range(0, n) :
             
            # Finds minimum of four inputs
            x = min(min(i, j), min(n - 1 - i, n - 1 - j))
             
            # For upper right half
            if (i <= j) :
                print((n - 2 * x) * (n - 2 * x) -
                      (i - x)- (j - x), end = "\t")
 
            # For lower left half
            else :
                print(((n - 2 * x - 2) *
                       (n - 2 * x - 2) +
                       (i - x) + (j - x)), end = "\t")
        print()
         
# Driver code
n = 5
 
# print a n x n spiral matrix
# in O(1) space
printSpiral(n)
 
# This code is contributed by Nikita Tiwari.


C#
// C# program to print a n x n
// spiral matrix in clockwise
// direction using O(1) space
using System;
 
class GFG {
 
    // Prints spiral matrix of
    // size n x n containing
    // numbers from 1 to n x n
    static void printSpiral(int n)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                 
                // x stores the layer in which
                // (i, j)th element lies
                int x;
 
                // Finds minimum of four inputs
                x = Math.Min(Math.Min(i, j),
                    Math.Min(n - 1 - i, n - 1 - j));
 
                // For upper right half
                if (i <= j)
                    Console.Write((n - 2 * x) *
                                  (n - 2 * x) -
                                  (i - x) - (j - x) + "\t");
 
                // for lower left half
                else
                    Console.Write((n - 2 * x - 2) *
                                  (n - 2 * x - 2) +
                                  (i - x) + (j - x) + "\t");
            }
            Console.WriteLine();
        }
    }
 
    // Driver code
    public static void Main()
    {
        int n = 5;
 
        // print a n x n spiral
        // matrix in O(1) space
        printSpiral(n);
    }
}
 
// This code is contributed by KRV


PHP


Javascript


输出 :

25     24     23     22     21     
10     9     8     7     20     
11     2     1     6     19     
12     3     4     5     18     
13     14     15     16     17