0

Possible duplicate - print spiral order matrix

I am trying to solve a question to print a matrix in a spiral manner. For eg, if Input: matrix = [[1,2,3],[4,5,6],[7,8,9]], Output: [1,2,3,6,9,8,7,4,5]

Here is my algorithm. It works as expected except I see 4 getting printed twice, and I really can't seem to figure out why.

public static void main(String[] args) {
        SprialMatrix spm = new SprialMatrix();
        int[][] inputArr = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
        int col = inputArr[0].length;
        int row = inputArr.length;
        spm.buildOutputArr(inputArr, row, col);

    }

    public void buildOutputArr(int[][] inputArr, int row, int column) {
        int top = 0, bottom = row - 1, left = 0, right = column - 1;
        int dir = 0;

        while (top <= bottom && left <= right) {
            // dir = 0, go from left to right
            if (dir == 0) {
                for (int i = left; i <= right; i++) {
                    System.out.println(inputArr[top][i]);
                }
            }

            else if (dir == 1) {
                // dir = 1, go from top to bottom
                top = top + 1;
                for (int i = top; i <= bottom; i++) {
                    System.out.println(inputArr[i][right]);
                }
            } else if (dir == 2) {
                // dir = 2, go from right to left
                right = right - 1;
                for (int i = right; i >= left; i--) {
                    System.out.println(inputArr[bottom][i]);
                }
            } else if (dir == 3) {
                // dir = 3, go from bottom to up
                bottom = bottom - 1;
                for (int i = bottom; i >= top; i--) {
                    System.out.println(inputArr[i][left]);
                }
            }
            dir = (dir + 1) % 4;
        }
    }

I can't seem to figure out what the issue is in my code. What can I try next?

halfer
  • 19,824
  • 17
  • 99
  • 186
rickygrimes
  • 2,637
  • 9
  • 46
  • 69
  • Did you try to debug the code? – Joakim Danielson Mar 28 '21 at 07:57
  • Did you notice that the array you're testing with isn't square? Does that matter for your algorithm? Why or why not? What result do you expect for that specific input? What happens when you try tracing through your algorithm manually, step by step? – Karl Knechtel Mar 28 '21 at 08:15
  • 1
    I notice that when `dir==1`, you modify `top`; when `dir==2`, you modify `right`; when `dir==3`, you modify `bottom`; but when `dir==0`, you don't modify anything (except for the local `i`). Does that make sense to you? Why? – Karl Knechtel Mar 28 '21 at 08:18

3 Answers3

0

For printing only square matrices

public static void printSpiral(int[][] m) {
    int s = m.length;
    for (int b = s - 1, c = 0, x = 0, y = 0, dx = 0, dy = 1; b > 0; b -= 2, x = y = ++c)
        for (int j = 0, t = 0; j < 4; ++j, t = dx, dx = dy, dy = -t)
            for (int i = 0; i < b; ++i, x += dx, y += dy)
                System.out.print(m[x][y] + " ");
    if (s % 2 == 1)
        System.out.print(m[s / 2][s / 2]);
    System.out.println();
}

And

int size = 5;
int[][] m = new int[size][size];
for (int i = 0, n = 1; i < size; ++i)
    for (int j = 0; j < size; ++j, ++n)
        m[i][j] = n;
for (int[] row : m)
    System.out.println(Arrays.toString(row));
printSpiral(m);

output:

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

Modify top, left, right and bottom after reading a line. In this way you avoid that the value of left is modified before reading from left to right for the first time.

The clockwise rule for this is:

  • Read left to right then top++
  • Read right to left then bottom--
  • Read top to bottom then right--
  • Read bottom to top then left++

I hope this helps you with the solution.

Edit:

I took your code and broke it down to what was necessary. As you can see, the management of the reading direction is not necessary, since all directions are processed in each loop pass anyway.

public class SprialMatrix {
    public static void main(String[] args) {
        int[][] matrix = { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}, {16, 17, 18, 19, 20} };
        System.out.println(Arrays.toString(new SprialMatrix().buildOutputArr(matrix)));
    }

    public int[] buildOutputArr(int[][] matrix){
        int left = 0;
        int top = 0;
        int right = matrix[1].length - 1;
        int bottom = matrix.length - 1;
        int size = matrix[1].length * matrix.length;
        int i = 0;
        int[] result = new int[size];

        while(i < size){
            for(int x = left; x <= right; x++) result[i++] = matrix[top][x];
            top++;
            for(int y = top; y <= bottom; y++) result[i++] = matrix[y][right];
            right--;
            for(int x = right; x >= left; x--)  result[i++] = matrix[bottom][x];
            bottom--;
            for(int y = bottom; y >= top; y--) result[i++] = matrix[y][left];
            left++;
        }

        return result;
    }
}
0
public class SpiralMatrix {
    public static void main(String[] args) {
        int[][] matrix = {{1,2,3}, {4,5,6}, {7,8,9}};
        int rows = matrix.length;
        int cols = matrix[0].length;
        int top = 0, bottom = rows - 1, left = 0, right = cols - 1;
        int dir = 0; // 0: right, 1: down, 2: left, 3: up
        int[] result = new int[rows * cols];
        int index = 0;
        while (top <= bottom && left <= right) {
            if (dir == 0) {
                for (int i = left; i <= right; i++) {
                    result[index++] = matrix[top][i];
                }
                top++;
            } else if (dir == 1) {
                for (int i = top; i <= bottom; i++) {
                    result[index++] = matrix[i][right];
                }
                right--;
            } else if (dir == 2) {
                for (int i = right; i >= left; i--) {
                    result[index++] = matrix[bottom][i];
                }
                bottom--;
            } else if (dir == 3) {
                for (int i = bottom; i >= top; i--) {
                    result[index++] = matrix[i][left];
                }
                left++;
            }
            dir = (dir + 1) % 4;
        }
        for (int i = 0; i < result.length; i++) {
            System.out.print(result[i] + " ");
        }
    } }
Lore
  • 1,286
  • 1
  • 22
  • 57