Print a given matrix in spiral using DFS

To solve the problem follow the below idea:

Another recursive approach is to consider DFS movement within the matrix (right->down->left->up->right->..->end). We do this by modifying the matrix itself such that when DFS algorithm visits each matrix cell it’s changed to a value which cannot be contained within the matrix. The DFS algorithm is terminated when it visits a cell such that all of its surrounding cells are already visited. The direction of the DFS search is controlled by a variable. 

Follow the given steps to solve the problem:

  • create a DFS function that takes matrix, cell indices, and direction
  • checks are cell indices pointing to a valid cell (that is, not visited and in bounds)? if not, skip this cell
  • print cell value
  • mark matrix cell pointed by indicates as visited by changing it to a value not supported in the matrix
  • check are surrounding cells valid? if not stop the algorithm, else continue
  • if the direction is given right then check, if the cell to the right is valid. if so, DFS to the right cell given the steps above, else, change the direction to down and DFS downwards given the steps above
  • else, if the direction given is down then check, if the cell to the down is valid. if so, DFS to the cell below given the steps above, else, change the direction to left and DFS leftwards given the steps above
  • else, if the direction given is left then check, if the cell to the left is valid. if so, DFS to the left cell given the steps above, else, change the direction to up and DFS upwards given the steps above
  • else, if the direction given is up then check, if the cell to the up is valid. if so, DFS to the upper cell given the steps above, else, change the direction to right and DFS rightwards given the steps above

Below is an implementation of the above approach: 

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
#define R 4
#define C 4
 
bool isInBounds(int i, int j)
{
    if (i < 0 || i >= R || j < 0 || j >= C)
        return false;
    return true;
}
 
// check if the position is blocked
bool isBlocked(int matrix[R][C], int i, int j)
{
    if (!isInBounds(i, j))
        return true;
    if (matrix[i][j] == -1)
        return true;
    return false;
}
 
// DFS code to traverse spirally
void spirallyDFSTraverse(int matrix[R][C], int i, int j,
                          int dir, vector<int>& res)
{
    if (isBlocked(matrix, i, j))
        return;
    bool allBlocked = true;
    for (int k = -1; k <= 1; k += 2) {
        allBlocked = allBlocked
                     && isBlocked(matrix, k + i, j)
                     && isBlocked(matrix, i, j + k);
    }
    res.push_back(matrix[i][j]);
    matrix[i][j] = -1;
    if (allBlocked) {
        return;
    }
 
    // dir: 0 - right, 1 - down, 2 - left, 3 - up
    int nxt_i = i;
    int nxt_j = j;
    int nxt_dir = dir;
    if (dir == 0) {
        if (!isBlocked(matrix, i, j + 1)) {
            nxt_j++;
        }
        else {
            nxt_dir = 1;
            nxt_i++;
        }
    }
    else if (dir == 1) {
        if (!isBlocked(matrix, i + 1, j)) {
            nxt_i++;
        }
        else {
            nxt_dir = 2;
            nxt_j--;
        }
    }
    else if (dir == 2) {
        if (!isBlocked(matrix, i, j - 1)) {
            nxt_j--;
        }
        else {
            nxt_dir = 3;
            nxt_i--;
        }
    }
    else if (dir == 3) {
        if (!isBlocked(matrix, i - 1, j)) {
            nxt_i--;
        }
        else {
            nxt_dir = 0;
            nxt_j++;
        }
    }
    spirallyDFSTravserse(matrix, nxt_i, nxt_j, nxt_dir,
                         res);
}
 
// To traverse spirally
vector<int> spirallyTraverse(int matrix[R][C])
{
    vector<int> res;
    spirallyDFSTravserse(matrix, 0, 0, 0, res);
    return res;
}
 
// Driver Code
int main()
{
    int a[R][C] = { { 1, 2, 3, 4 },
                    { 5, 6, 7, 8 },
                    { 9, 10, 11, 12 },
                    { 13, 14, 15, 16 } };
 
    // Function Call
    vector<int> res = spirallyTraverse(a);
    int size = res.size();
    for (int i = 0; i < size; ++i)
        cout << res[i] << " ";
    cout << endl;
    return 0;
} // code contributed by Ephi F


Java




// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
    public static int R = 4, C = 4;
    public static boolean isInBounds(int i, int j)
    {
        if (i < 0 || i >= R || j < 0 || j >= C)
            return false;
        return true;
    }
 
    // check if the position is blocked
    public static boolean isBlocked(int[][] matrix, int i,
                                    int j)
    {
        if (!isInBounds(i, j))
            return true;
        if (matrix[i][j] == -1)
            return true;
        return false;
    }
 
    // DFS code to traverse spirally
    public static void
    spirallyDFSTraverse(int[][] matrix, int i, int j,
                         int dir, ArrayList<Integer> res)
    {
        if (isBlocked(matrix, i, j))
            return;
        boolean allBlocked = true;
        for (int k = -1; k <= 1; k += 2) {
            allBlocked = allBlocked
                         && isBlocked(matrix, k + i, j)
                         && isBlocked(matrix, i, j + k);
        }
        res.add(matrix[i][j]);
        matrix[i][j] = -1;
        if (allBlocked) {
            return;
        }
 
        // dir: 0 - right, 1 - down, 2 - left, 3 - up
        int nxt_i = i;
        int nxt_j = j;
        int nxt_dir = dir;
        if (dir == 0) {
            if (!isBlocked(matrix, i, j + 1)) {
                nxt_j++;
            }
            else {
                nxt_dir = 1;
                nxt_i++;
            }
        }
        else if (dir == 1) {
            if (!isBlocked(matrix, i + 1, j)) {
                nxt_i++;
            }
            else {
                nxt_dir = 2;
                nxt_j--;
            }
        }
        else if (dir == 2) {
            if (!isBlocked(matrix, i, j - 1)) {
                nxt_j--;
            }
            else {
                nxt_dir = 3;
                nxt_i--;
            }
        }
        else if (dir == 3) {
            if (!isBlocked(matrix, i - 1, j)) {
                nxt_i--;
            }
            else {
                nxt_dir = 0;
                nxt_j++;
            }
        }
        spirallyDFSTravserse(matrix, nxt_i, nxt_j, nxt_dir,
                             res);
    }
 
    // to traverse spirally
    public static ArrayList<Integer>
    spirallyTraverse(int[][] matrix)
    {
        ArrayList<Integer> res = new ArrayList<Integer>();
        spirallyDFSTravserse(matrix, 0, 0, 0, res);
        return res;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int a[][] = { { 1, 2, 3, 4 },
                      { 5, 6, 7, 8 },
                      { 9, 10, 11, 12 },
                      { 13, 14, 15, 16 } };
 
        // Function Call
        ArrayList<Integer> res = spirallyTraverse(a);
        int size = res.size();
        for (int i = 0; i < size; ++i)
            System.out.print(res.get(i) + " ");
        System.out.println();
    }
}
 
// This code is contributed by Manu Pathria


Python3




# Python3 program for the above approach
 
R = 4
C = 4
 
 
def isInBounds(i, j):
    global R
    global C
    if (i < 0 or i >= R or j < 0 or j >= C):
        return False
    return True
 
# Check if the position is blocked
 
 
def isBlocked(matrix, i, j):
    if (not isInBounds(i, j)):
        return True
    if (matrix[i][j] == -1):
        return True
 
    return False
 
# DFS code to traverse spirally
 
 
def spirallyDFSTraverse(matrix, i, j, Dir, res):
    if (isBlocked(matrix, i, j)):
        return
 
    allBlocked = True
    for k in range(-1, 2, 2):
        allBlocked = allBlocked and isBlocked(
            matrix, k + i, j) and isBlocked(matrix, i, j + k)
 
    res.append(matrix[i][j])
    matrix[i][j] = -1
    if (allBlocked):
        return
 
    # dir: 0 - right, 1 - down, 2 - left, 3 - up
    nxt_i = i
    nxt_j = j
    nxt_dir = Dir
    if (Dir == 0):
        if (not isBlocked(matrix, i, j + 1)):
            nxt_j += 1
        else:
            nxt_dir = 1
            nxt_i += 1
 
    elif(Dir == 1):
        if (not isBlocked(matrix, i + 1, j)):
            nxt_i += 1
        else:
            nxt_dir = 2
            nxt_j -= 1
 
    elif(Dir == 2):
        if (not isBlocked(matrix, i, j - 1)):
            nxt_j -= 1
        else:
            nxt_dir = 3
            nxt_i -= 1
 
    elif(Dir == 3):
        if (not isBlocked(matrix, i - 1, j)):
            nxt_i -= 1
        else:
            nxt_dir = 0
            nxt_j += 1
 
    spirallyDFSTravserse(matrix, nxt_i, nxt_j, nxt_dir, res)
 
# To traverse spirally
 
 
def spirallyTraverse(matrix):
    res = []
    spirallyDFSTravserse(matrix, 0, 0, 0, res)
    return res
 
 
# Driver code
if __name__ == "__main__":
    a = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
 
    # Function Call
    res = spirallyTraverse(a)
    print(*res)
 
# This code is contributed by rag2127


C#




// C# program for the above approach
 
using System;
using System.Collections.Generic;
 
class GFG {
 
    public static int R = 4, C = 4;
    public static bool isInBounds(int i, int j)
    {
        if (i < 0 || i >= R || j < 0 || j >= C)
            return false;
 
        return true;
    }
 
    // Check if the position is blocked
    public static bool isBlocked(int[, ] matrix, int i,
                                 int j)
    {
        if (!isInBounds(i, j))
            return true;
        if (matrix[i, j] == -1)
            return true;
        return false;
    }
 
    // DFS code to traverse spirally
    public static void spirallyDFSTraverse(int[, ] matrix,
                                            int i, int j,
                                            int dir,
                                            List<int> res)
    {
        if (isBlocked(matrix, i, j))
            return;
 
        bool allBlocked = true;
 
        for (int k = -1; k <= 1; k += 2) {
            allBlocked = allBlocked
                         && isBlocked(matrix, k + i, j)
                         && isBlocked(matrix, i, j + k);
        }
        res.Add(matrix[i, j]);
        matrix[i, j] = -1;
 
        if (allBlocked) {
            return;
        }
 
        // dir: 0 - right, 1 - down, 2 - left, 3 - up
        int nxt_i = i;
        int nxt_j = j;
        int nxt_dir = dir;
        if (dir == 0) {
            if (!isBlocked(matrix, i, j + 1)) {
                nxt_j++;
            }
            else {
                nxt_dir = 1;
                nxt_i++;
            }
        }
        else if (dir == 1) {
            if (!isBlocked(matrix, i + 1, j)) {
                nxt_i++;
            }
            else {
                nxt_dir = 2;
                nxt_j--;
            }
        }
        else if (dir == 2) {
            if (!isBlocked(matrix, i, j - 1)) {
                nxt_j--;
            }
            else {
                nxt_dir = 3;
                nxt_i--;
            }
        }
        else if (dir == 3) {
            if (!isBlocked(matrix, i - 1, j)) {
                nxt_i--;
            }
            else {
                nxt_dir = 0;
                nxt_j++;
            }
        }
        spirallyDFSTravserse(matrix, nxt_i, nxt_j, nxt_dir,
                             res);
    }
 
    // To traverse spirally
    public static List<int> spirallyTraverse(int[, ] matrix)
    {
        List<int> res = new List<int>();
        spirallyDFSTravserse(matrix, 0, 0, 0, res);
        return res;
    }
 
    // Driver code
    static public void Main()
    {
        int[, ] a = { { 1, 2, 3, 4 },
                      { 5, 6, 7, 8 },
                      { 9, 10, 11, 12 },
                      { 13, 14, 15, 16 } };
 
        // Function Call
        List<int> res = spirallyTraverse(a);
        int size = res.Count;
 
        for (int i = 0; i < size; ++i)
            Console.Write(res[i] + " ");
 
        Console.WriteLine();
    }
}
 
// This code is contributed by avanitrachhadiya2155


Javascript




<script>
 
var R = 4, C = 4;
function isInBounds(i, j)
{
    if (i < 0 || i >= R || j < 0 || j >= C)
        return false;
    return true;
}
// Check if the position is blocked
function isBlocked(matrix, i, j)
{
    if (!isInBounds(i, j))
        return true;
    if (matrix[i][j] == -1)
        return true;
    return false;
}
// DFS code to traverse spirally
function spirallyDFSTraverse(matrix, i, j, dir, res)
{
    if (isBlocked(matrix, i, j))
        return;
    var allBlocked = true;
    for (var k = -1; k <= 1; k += 2) {
        allBlocked = allBlocked
                     && isBlocked(matrix, k + i, j)
                     && isBlocked(matrix, i, j + k);
    }
    res.push(matrix[i][j]);
    matrix[i][j] = -1;
    if (allBlocked) {
        return;
    }
    // dir: 0 - right, 1 - down, 2 - left, 3 - up
    var nxt_i = i;
    var nxt_j = j;
    var nxt_dir = dir;
    if (dir == 0) {
        if (!isBlocked(matrix, i, j + 1)) {
            nxt_j++;
        }
        else {
            nxt_dir = 1;
            nxt_i++;
        }
    }
    else if (dir == 1) {
        if (!isBlocked(matrix, i + 1, j)) {
            nxt_i++;
        }
        else {
            nxt_dir = 2;
            nxt_j--;
        }
    }
    else if (dir == 2) {
        if (!isBlocked(matrix, i, j - 1)) {
            nxt_j--;
        }
        else {
            nxt_dir = 3;
            nxt_i--;
        }
    }
    else if (dir == 3) {
        if (!isBlocked(matrix, i - 1, j)) {
            nxt_i--;
        }
        else {
            nxt_dir = 0;
            nxt_j++;
        }
    }
    spirallyDFSTravserse(matrix, nxt_i, nxt_j, nxt_dir,
                         res);
}
// To traverse spirally
function spirallyTraverse(matrix)
{
    var res = [];
    spirallyDFSTravserse(matrix, 0, 0, 0, res);
    return res;
}
// Driver code
var a = [ [ 1, 2, 3, 4 ],
              [ 5, 6, 7, 8 ],
              [ 9, 10, 11, 12 ],
              [ 13, 14, 15, 16 ]];
// Function Call
var res = spirallyTraverse(a);
var size = res.length;
for (var i = 0; i < size; ++i)
    document.write(res[i] + " ");
 
</script>


Output

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

Time Complexity: O(M*N). To traverse the matrix O(M*N) time is required.
Auxiliary Space: O(1). No extra space is required (without consideration of the stack used by the recursion). 

 

Please write comments if you find the above code incorrect, or find other ways to solve the same problem. 



Print a given matrix in spiral form

Given a 2D array, print it in spiral form.

Examples: 

Input:  {{1,    2,   3,   4},
              {5,    6,   7,   8},
             {9,   10,  11,  12},
            {13,  14,  15,  16 }}
Output: 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 
Explanation: The output is matrix in spiral format. 

Input: { {1,   2,   3,   4,  5,   6},
           {7,   8,   9,  10,  11,  12},
          {13,  14,  15, 16,  17,  18}}

Output: 1 2 3 4 5 6 12 18 17 16 15 14 13 7 8 9 10 11
Explanation: The output is matrix in spiral format.

Recommended Practice

Similar Reads

Print a given matrix in spiral form using the simulation approach:

To solve the problem follow the below idea:...

Print a given matrix in spiral form by dividing the matrix into cycles:

...

Print a given matrix in a spiral using recursion:

...

Print a given matrix in spiral using DFS:

...