Monday, May 5, 2014

LeetCode: Spiral Matrix

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

For example,
Given the following matrix:

[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

You should return [1,2,3,6,9,8,7,4,5].


We can iterate the matrix by a top, right, bottom, left order to traverse each element. I implemented recursive method in C++, iterative method in Python.

C++ Code:

/*
 * func: spiral_order_helper
 * goal: helper function for spiral_order
 * @param matrix: input matrix
 * @param start_row: starting point row index
 * @param start_column: starting point column index
 * @param row_bound: row range
 * @param column_bound: column range
 * @param result: vector storing output
 * return:
 */
void spiral_order_helper(const vector<vector<int>> &matrix, int start_row, int start_column, int row_bound, int column_bound, vector<int> &result){
    //All elements are already added
    if(start_row >= row_bound || start_column >= column_bound){
        return;
    }
    
    //There is only one row
    if(start_row + 1 == row_bound){
        for(int i = start_column; i < column_bound; ++i){
            result.emplace_back(matrix[start_row][i]);
        }
        return;
    }
    //There is only one column
    if(start_column + 1 == column_bound){
        for(int i = start_row; i < row_bound; ++i){
            result.emplace_back(matrix[i][start_column]);
        }
        return;
    }
    
    //Add upside row
    for(int i = start_column; i < column_bound; ++i){
        result.emplace_back(matrix[start_row][i]);
    }
    //Add rightside column
    for(int i = start_row+1; i < row_bound; ++i){
        result.emplace_back(matrix[i][column_bound-1]);
    }
    //Add bottom row
    for(int i = column_bound-2; i >= start_column; --i){
        result.emplace_back(matrix[row_bound-1][i]);
    }
    //Add leftside column
    for(int i = row_bound-2; i > start_row; --i){
        result.emplace_back(matrix[i][start_column]);
    }
    
    //Continue for the inner matrix
    spiral_order_helper(matrix, start_row+1, start_column+1, row_bound-1, column_bound-1, result);
}

/*
 * func: spiral_order
 * goal: output the input matrix in spiral order
 * @param matrix: input matrix
 * return: spiral order output in a vector
 */
vector<int> spiral_order(const vector<vector<int> > &matrix){
    vector<int> result;
    if(matrix.size() == 0){
        return result;
    }
    int m = static_cast<int>(matrix.size());
    int n = static_cast<int>(matrix[0].size());
    spiral_order_helper(matrix, 0, 0, m, n, result);
    return result;
}

Python Code:

# func: find the spiral traversal of a m*n matrix
# @param matrix: input matrix
# @return: a list of spiral traversal ordered elements
def spiral_order(matrix):
    if matrix:
        result = []
        begin_x = 0
        begin_y = 0
        end_x = len(matrix)-1
        end_y = len(matrix[0])-1
        while True:
            #Upside traversal
            i = begin_y
            while i <= end_y:
                result.append(matrix[begin_x][i])
                i += 1
            #Update upperside index
            begin_x += 1
            if begin_x > end_x:
                break
            #Rightside traversal
            i = begin_x
            while i <= end_x:
                result.append(matrix[i][end_y])
                i += 1
            #Update rightside index
            end_y -= 1
            if begin_y > end_y:
                break
            #Bottomside traversal
            i = end_y
            while i >= begin_y:
                result.append(matrix[end_x][i])
                i -= 1
            #Update bottomside index
            end_x -= 1
            if begin_x > end_x:
                break
            #Leftside traversal
            i = end_x
            while i >= begin_x:
                result.append(matrix[i][begin_y])
                i -= 1
            #Update leftside index
            begin_y += 1
            if begin_y > end_y:
                break

        return result
    else:
        return []

No comments:

Post a Comment