Skip to content

花式访问矩阵

基本思路

卡边界

访问

//定义上下左右边界,逐步缩小边界的做法
vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector <int> ans;
        if(matrix.empty()) return ans; //若数组为空,直接返回答案
        int u = 0; //赋值上下左右边界
        int d = matrix.size() - 1;
        int l = 0;
        int r = matrix[0].size() - 1;
        while(true)
        {
            for(int i = l; i <= r; ++i) ans.push_back(matrix[u][i]); //向右移动直到最右
            if(++ u > d) break; //重新设定上边界,若上边界大于下边界,则遍历遍历完成,下同
            for(int i = u; i <= d; ++i) ans.push_back(matrix[i][r]); //向下
            if(-- r < l) break; //重新设定右边界
            for(int i = r; i >= l; --i) ans.push_back(matrix[d][i]); //向左
            if(-- d < u) break; //重新设定下边界
            for(int i = d; i >= u; --i) ans.push_back(matrix[i][l]); //向上
            if(++ l > r) break; //重新设定左边界
        }
        return ans;
}

赋值

//顺时针螺旋填充矩阵
//定义上下左右边界,逐步缩小边界的做法
vector<vector<int>> spiralMatrix(int m, int n, ListNode* head) {
        vector<vector<int>> matrix(m,vector<int>(n,-1));
        int nullptr_flag=0;
        int u = 0; //赋值上下左右边界
        int d = matrix.size() - 1;
        int l = 0;
        int r = matrix[0].size() - 1;
        while(true)
        {
            for(int i = l; i <= r; ++i){
                matrix[u][i]=head->val; //向右移动直到最右
                if(head->next==nullptr) {
                    nullptr_flag=1;
                    break;
                } 
                head=head->next;
            } 
            if(++ u > d || nullptr_flag) break; //重新设定上边界,若上边界大于下边界,则遍历遍历完成,下同


            for(int i = u; i <= d; ++i){
                matrix[i][r]=head->val; //向下
                if(head->next==nullptr) {
                    nullptr_flag=1;
                    break;
                } 
                head=head->next;
            } 
            if(-- r < l || nullptr_flag) break; //重新设定右边界


            for(int i = r; i >= l; --i){
                matrix[d][i]=head->val;
                if(head->next==nullptr) {
                    nullptr_flag=1;
                    break;
                }
                head=head->next;
            }//向左
            if(-- d < u || nullptr_flag)  break; //重新设定下边界


            for(int i = d; i >= u; --i){
                matrix[i][l]=head->val;
                if(head->next==nullptr) {
                    nullptr_flag=1;
                    break;
                }
                head=head->next;
            } 
            if(++ l > r || nullptr_flag) break; //重新设定左边界

        }
        return matrix;

}

按方向走

赋值

// 根据方向走迷宫的做法
// 四个方向,按右、下、左、上顺序记录(因为螺旋也是按这个顺序转的)
short dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
vector<vector<int>> spiralMatrix(int n, int m, ListNode* head) {
        // 初始化答案矩阵,并将所有位置设为 -1
        vector<vector<int>> ans(m,vector<int>(n,-1));
        // (i, j) 是当前矩阵中的坐标,D 是当前的方向
        int i = 0, j = 0, D = 0;
        while (true) {
            // 填写当前位置
            ans[i][j] = head->val;
            head = head->next;
            // 已经没有下一个位置要填了,退出
            if (head == nullptr) break;
            // 算出下一个位置的坐标
            while (true) {
                // 试着往当前方向走一步
                int ii = i + dir[D][0], jj = j + dir[D][1];
                // 会走出矩阵或走到已有数字的格子中,换一个方向
                if (ii < 0 || jj < 0 || ii >= n || jj >= m || ans[ii][jj] >= 0) D = (D + 1) % 4;//方向转换通过取模快速实现
                else {
                    // 走到下一个格子
                    i = ii;
                    j = jj;
                    break;
                }
            }
        }
        return ans;
    }