javascriptalgorithmrecursion

Any Idea or solution to this matrix challenge?


I was just wondering how to solve this spiral matrix Challenge:

Have the function MatrixSpiral(strArr) read the array of strings stored in strArr which will represent a 2D N matrix, and your program should return the elements after printing them in a clockwise, spiral order. You should return the newly formed list of elements as a string with the numbers separated by commas. For example: input:

["[4, 5, 6, 5]",   
 "[1, 1, 2, 2]",  
 "[5, 4, 2, 9]"]   

Output:

"4,5,6,5,2,9,2,4,5,1,1,2"

I have done simple matrix spiral before, but don't know how to solve one like this.

This is not a simple matrix spiral. I tried with this code, but output is way different

The input is an array of "string arrays" (see the double quotes), and the output should be a string with the numbers separated by commas.

const spiralOrder = (matrix) => {

if(!matrix.length || !matrix[0].length){
        return [];
}
//Use 4 pointes to create wall around square
let rowBegin = 0,
    rowEnd = matrix.length - 1,
    colBegin = 0,
    colEnd = matrix[0].length - 1;

let result = [];
while(rowBegin <= rowEnd && colBegin <= colEnd){

    //move right
    for(let i= colBegin; i<= colEnd; i++){
            result.push(matrix[rowBegin][i]);
    }
    rowBegin++; // mark row as traversed after moving right

    //move down
    for(let i=rowBegin; i<= rowEnd; i++){
            result.push(matrix[i][colEnd]);
    }
    colEnd--; //mark column as traversed after moving down

    //move left
    if(rowBegin <= rowEnd){
            for(let i=colEnd; i >= colBegin; i--){
                    result.push(matrix[rowEnd][i]); 
            }
    }
    rowEnd--; //mark end row as traversed after moving left

    //move up
    if(colBegin <= colEnd){ 
            for(let i=rowEnd; i >= rowBegin; i--){
                    result.push(matrix[i][colBegin]);
            }
    }
    colBegin++; //mark begining column as traversed after moving up
}

return result;
};

spiralOrder([[4, 5, 6, 5], [1, 1, 2, 2], [5, 4, 2, 9]])

Output: [ '[',
  '4',
  ',',
  ' ',
  '5',
  ',',
  ' ',
  '6',
  ',',
  ' ',
  '5',
  ']',
  ']',
  ']',
  '9',
  ' ',
  ',',
  '2',
  ' ',
  ',',
  '4',
  ' ',
  ',',
  '5',
  '[',
  '[',
  '1',
  ',',
  ' ',
  '1',
  ',',
  ' ',
  '2',
  ',',
  ' ',
  '2' ]

Could you please share any solution?


Solution

  • You could take an approach with four directions and an index pair (i/j), as well as four more variables for limiting the loops with upper and lower bound, as well as left and right limits.

    After taking a limit, the limit is checked an incremented or decremented. If the limit is not inside of the wanted range, the loops ends.

    At the end, the left over item is added to the result set.

    function getSpiral(data) {
        var array = data.map(j => JSON.parse(j)),
            upper = 0,
            lower = array.length - 1,
            left = 0,
            right = array[0].length - 1,
            i = upper,
            j = left,
            result = [];
    
        while (true) {
            if (upper++ > lower) break;
    
            for (; j < right; j++) result.push(array[i][j]);
            if (right-- < left) break;
    
            for (; i < lower; i++) result.push(array[i][j]);
            if (lower-- < upper) break;
    
            for (; j > left; j--) result.push(array[i][j]);
            if (left++ > right) break;
    
            for (; i > upper; i--) result.push(array[i][j]);
        }
        result.push(array[i][j]);
    
        return result.join(',');
    }
    
    console.log(getSpiral(['[4, 5, 6, 5]', '[1, 1, 2, 2]', '[5, 4, 2, 9]']));
    console.log(getSpiral(['[1, 2, 3, 4, 5]', '[6, 7, 8, 9, 10]', '[11, 12, 13, 14, 15]', '[16, 17, 18, 19, 20]']));