Chronus Interview Question
Software Engineer / DevelopersCountry: India
Interview Type: Phone Interview
I found the solution in "Print 2D array in spiral order" of the book "Elements of Programming Interviews: 300 Questions and Solutions". They have code in the entry "Print 2D array in spiral order" at code.google.com/p/elements-of-programming-interviews/wiki/Programs
They have recursive and iterative implementations.
The trick is to have another 2d array with same m rows and rows to record whether the element has been visited. The C++ code for the same,
#include<iostream>
using namespace std;
bool allvisited(int visited[][3])
{
//bool visited = false;
for(int i=0 ; i<3 ; i++)
{
for(int j=0 ; j <3; j++)
if(visited[i][j] == 0)
return false;
}
return true;
}
int main()
{
int mat[3][3] = { 1,2,3,
4,5,6,
7,8,9 };
int visited[3][3] = {0};
int currenti,currentj,tempi,tempj,lefttoright,toptobottom;
int m=3 , n=3;
currenti=currentj=lefttoright=toptobottom = tempi = tempj =0;
while(!allvisited(visited))
{
if(!lefttoright)
{ tempj = currentj;
while(currentj < n)
{
if(visited[currenti][currentj] == 0)
{
visited[currenti][currentj] = 1;
cout << mat[currenti][currentj] << " ";
tempj = currentj;
}
currentj ++ ;
}
currentj = tempj ; //resetting
}
else
{
tempj = currentj;
while(currentj >= 0)
{
if(visited[currenti][currentj] == 0)
{
visited[currenti][currentj] = 1;
cout << mat[currenti][currentj] << " ";
tempj = currentj;
}
currentj -- ;
}
currentj = tempj ; //resetting
}
if(!toptobottom)
{ tempi = currenti;
while(currenti < m)
{
if(visited[currenti][currentj] == 0)
{
visited[currenti][currentj] = 1;
cout << mat[currenti][currentj] << " ";
tempi = currenti;
}
currenti ++ ;
}
currenti = tempi ; //resetting
}
else
{ tempi = currenti;
while(currenti >= 0)
{
if(visited[currenti][currentj] == 0)
{
visited[currenti][currentj] = 1;
cout << mat[currenti][currentj] << " ";
tempi = currenti;
}
currenti -- ;
}
currenti = tempi ; //resetting
}
lefttoright = !lefttoright;
toptobottom = !toptobottom;
}
cout << endl << "All visited\n";
return 0;
}
import java.util.Scanner;
public class spiralNumber {
public static void main(String[] args)
{
System.out.print("Enter the width: ");
Scanner in = new Scanner(System.in);
int width = in.nextInt();
System.out.print("Enter the height: ");
int height = in.nextInt();
int value[][] = new int[height][width];
int direction = 1; // left to right
int row=0;
int col=0;
for(int i=0;i<width*height;i++){
if(value[row][col]==0){
value[row][col]=i+1;
if(direction==1){
if(col+1<width && value[row][col+1]==0){
col++;
}else{
direction=2; // top to bottom
row++;
}
}else if(direction==2){
if(row+1<height && value[row+1][col]==0){
row++;
}else{
direction=3; // right to left
col--;
}
}else if(direction==3){
if(col-1>=0 && value[row][col-1]==0){
col--;
}else{
direction=4; // bottom to top
row--;
}
}else{
if(row-1>=0 && value[row-1][col]==0){
row--;
}else{
direction=1;
col++;
}
}
}
}
String string = "%" + String.valueOf(width*height).length() + "d ";
for(int i=0;i<height;i++){
for(int j=0;j<width;j++)
System.out.printf(string, value[i][j]);
System.out.println();
}
}
}
#include<iostream>
using namespace std;
int main()
{
int n;
cout<<endl<<"enter n:";
cin>>n;
int a[n][n],i,j,m;
for (i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
a[i][j]=(i*n)+(j+1);
}
}
if(n%2==0)
m=n/2;
else
m = (int) n/2+1;
for(int k=0;k<=m;k++)
{
cout<<endl;
for (j=k;j<n-k;j++)
{
i=k;
cout<<"\t"<<a[i][j];
}
cout<<endl;
for(i=k+1;i<n-k;i++)
{
j=n-1-k;
cout<<"\t"<<a[i][j];
}
cout<<endl;
for(j=n-2-k;j>=0+k;j--)
{
i=n-1-k;
cout<<"\t"<<a[i][j];
}
cout<<endl;
for(i=n-2-k;i>=1+k;i--)
{
j=0+k;
cout<<"\t"<<a[i][j];
}
}
}
Java Code
int[][] arr = {{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}};
int size = arr.length;
int width = arr[0].length;
for (int l = 0; l < size / 2; l++)
{
int min = l;
int max = size - 1 - l;
int max1 = width-1 -l;
for (int i = min; i < max; i++)
System.out.print("\t" + arr[i][min]);
for (int j = min; j < max1; j++)
System.out.print("\t" + arr[max][j]);
for (int i = max; i > min; i--)
System.out.print("\t" + arr[i][max1]);
for (int j = max1; j > min; j--)
System.out.print("\t" + arr[min][j]);
}
// centre is special case: avoiding printing it 4 times.
if (size % 2 == 1)
System.out.print("\t" + arr[size / 2][size / 2]);
I think the matrix can be split into levels, such as 1, 2, 3,
4, 5, 6,
7, 8, 9,
we can takes it as two levels: 1, 2, 3, 6, 9, 8, 7, 4 and 5 respetively. and print in level, here are my codes, there is no need extra space and time complexicity is O(n*n), or O(n).
#include<iostream>
using namespace std;
const int n = 5;
int a[n][n] = {1, 2, 3, 4, 5, 16, 17, 18, 19, 6, 15, 24, 25, 20, 7, 14, 23, 22, 21, 8, 13, 12, 11, 10, 9};
void spiral_traverse() {
int level;
int i;
for(level = 1; level <= n / 2; level++) {
for(i = level - 1; i < n - level; i++) {
cout << a[level - 1][i] << " ";
}
for(i = level - 1; i < n - level; i++) {
cout << a[i][n - level] << " ";
}
for(i = n - level; i >= level; i--) {
cout << a[n - level][i] << " ";
}
for(i = n - level; i >= level; i--) {
cout << a[i][level - 1] << " ";
}
}
if(n % 2 == 1) {
cout << a[n / 2][n / 2];
}
cout << endl;
}
void main() {
spiral_traverse();
getchar();
}
This is my code an it works well.
sort the matrix in an array and then map the pattern traversal in it u will come to know about it.
#include<stdio.h>
#include<conio.h>
#include<Windows.h>
int main()
{
int i=0,j=0,k=0,b=0,l=0,m=0,n=0;
int giv[25][25],in[25],out[25];
puts("\nEnter the order of the matrix->");
scanf_s("%d",&m);
puts("Enter the matrix ->");
for(i=0;i<m;i++)
{ for(j=0;j<m;j++)
scanf_s("%d",&giv[i][j]);
puts("");
}
for(i=0;i<m;i++)
{ for(j=0;j<m;j++)
{ in[k]=giv[i][j];
k++;
}
}
system("cls");
puts("\nEntered matix is\n ");
for(i=0;i<m;i++)
{ for(j=0;j<m;j++)
printf("%4d",giv[i][j]);
puts("");
}
b=(m*m)/2;
out[0]=in[b];
j=1;
/*this is the main procedure try to map it using an array of no.s*/
while(l<m)
{ for(k=1;k<=m;k++)
{ n=k;
if(n%2==0)
{
for(i=1;i<=n;i++)
{
out[j]=in[b+m];
j++;
b=b+m;
}
for(i=1;i<=n;i++)
{
out[j]=in[b+1];
j++;
b=b+1;
}l++;
}
if(n%2==1)
{
for(i=1;i<=n;i++)
{
out[j]=in[b-m];
j++;
b=b-m;
}
for(i=1;i<=n;i++)
{ out[j]=in[b-1];
j++;
b=b-1;
}l++;
}
}
}
printf("\noutput is-> ");
printf("%d",out[0]);
for(i=1;i<(m*m);i++)
{ printf("-");
printf("%d",out[i]);
}
_getch();
return 0;
}
Recursive call might be cleaner and easier.
public class SpiralPrint{
//print the elements of matrix in the spiral order.
//my idea is to use recursive, for each outer loop
public static void printSpiral(int[][] mat, int layer){
int up = layer;
int buttom = mat.length - layer - 1;
int left = layer;
int right = mat[0].length - layer - 1;
if(up > buttom+1 || left > right + 1)
return; // termination condition
//traverse the other frame,
//print up
for(int i = left; i <= right; i ++){
System.out.print( mat[up][i]+ " " );
}
//print right
for(int i = up + 1; i <=buttom; i ++){
System.out.print(mat[i][right] + " ");
}
//print buttom
for(int i = right - 1; i >= left; i --){
System.out.print(mat[buttom][i] + " ");
}
//print left
for(int i = buttom - 1; i > up; i --){
System.out.print(mat[i][left] + " ");
}
//recursive call for the next level
printSpiral(mat, layer + 1);
}
public static void main(String[] args){
int[][] mat = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16}};
int[][] mat2 = {{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}};
SpiralPrint.printSpiral(mat2,0);
return;
}
}
sample input:
- int80h January 28, 2013dArray1 = [[1,2,3],[8,9,4],[7,6,5]]
dArray2 = [[10,11],[13,12]]
dArray3 = [[14]]
dArray4 = [[1,2,3,4],[12,13,14,5],[11,16,15,6],[10,9,8,7]]
spiralPrint(dArray1,0,0,2,2)
spiralPrint(dArray2,0,0,1,1)
spiralPrint(dArray3,0,0,0,0)
spiralPrint(dArray4,0,0,3,3)