力扣每日一题--螺旋矩阵

题目描述

给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:

输入: 3
输出:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析

顺时针螺旋排矩阵解决步骤如下:

每画一个边界正方形需要:—不断循环该步骤。画出矩阵

  • 最上行从左向右
  • 最右行从上到下
  • 最下行从右到左
  • 最左行 从下到上
    **注意:**在进行以上4个循环时,条件的判断,坚持循环不变量原则

循环该步骤判断条件:

  • 根据n计算出需要几个圈loop:n/2
  • 或者:每次填充矩阵的count<=n*n

若是奇数,在最*位置n*n

代码如下:

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] result = new int[n][n];
        int loop=n/2; //需要循环填充几个圈
        int startx=0,starty=0;//每个圈的起始位置
        int mid=n/2; //中间位置
        int count=1; // 给每一个元素赋值用
        int offset=1; //给每次循环长度改变
        int i,j;

        while(loop-->0){   //填充一个圈
            i=startx;j=starty;
            //最上边 从左向右 [starty,starty+n-offset)
            for(j = starty; j < starty + n - offset; j++){//循环遍历长度需要变
                result[i][j] = count++;
            }
            //最右边从上到下[,)
            for(i = startx; i < startx + n - offset; i++){
                result[i][j] = count++;
            }
            //最下边 从右到左
             for(; j > starty; j--){//循环遍历长度需要变
                result[i][j] = count++;
            }
            //最左边  从下到上
            for(;i>startx;i--){
                result[i][j]=count++;
            }
            offset+=2;
            startx++;
            starty++;
        }

        if(n%2 == 1) {
            result[mid][mid]=n*n;
        }
        
    return result;
    }
}

解决思路:限定边界

思路见代码:

class Solution {
    public int[][] generateMatrix(int n) {
    //     int[][] result = new int[n][n];
    //     int loop=n/2; //需要循环填充几个圈
    //     int startx=0,starty=0;//每个圈的起始位置
    //     int mid=n/2; //中间位置
    //     int count=1; // 给每一个元素赋值用
    //     int offset=1; //给每次循环长度改变
    //     int i,j;

    //     while(loop-->0){   //填充一个圈
    //         i=startx;j=starty;
    //         //最上边 从左向右
    //         for(j = starty; j < starty + n - offset; j++){//循环遍历长度需要变
    //             result[i][j] = count++;
    //         }
    //         //最右边从上到下
    //         for(i = startx; i < startx + n - offset; i++){
    //             result[i][j] = count++;
    //         }
    //         //最下边 从右到左
    //          for(; j > starty; j--){//循环遍历长度需要变
    //             result[i][j] = count++;
    //         }
    //         //最左边  从下到上
    //         for(;i>startx;i--){
    //             result[i][j]=count++;
    //         }
    //         offset+=2;
    //         startx++;
    //         starty++;
    //     }

    //     if(n%2 == 1) {
    //         result[mid][mid]=n*n;
    //     }
        
    // return result;

    /*
    控制边界方法:
    设定上、下、左、右的边界
        从左到右  
        从上到下  
        从右到左  
        从下到上  
    更新边界
    -->更新上边界
    -->更新右边界 
    -->更新下边界 
    -->更新左边界 
    */
    int result[][] = new int[n][n];
    int count = 1; // 用来填充矩阵中的每一个元素
    int end = n*n;
    int up=0,right=n-1,down=n-1,left=0;
    int mid=n/2;

    // while(count <= end){
    //     // 四个for循环进行填充    左闭右开  当n为奇数时无法填充最后一个元素     改为左闭右闭区间
    //     for(int i = left; i < right; i++) {result[up][i] = count++;} //上:左-->右   
       
    //     for(int j = up; j < down; j++) {result[j][right] = count++;} //右:上-->下   

    //     for(int i = right; i > left; i--) {result[down][i] = count++;} //下:右-->左

    //     for(int j = down; j > up; j--) {result[j][left] = count++;} //左:下-->上

    //     //更新边界
    //     up++;right--;down--;left++;
    // }
     while(count <= end){
        // 四个for循环进行填充    改为:左闭右闭区间    更新边界需要在每一次for循环后
        for(int i = left; i <= right; i++) {result[up][i] = count++;} //上:左-->右   
        up++;

        for(int j = up; j <= down; j++) {result[j][right] = count++;} //右:上-->下
        right--;   

        for(int i = right; i >= left; i--) {result[down][i] = count++;} //下:右-->左
        down--;

        for(int j = down; j >= up; j--) {result[j][left] = count++;} //左:下-->上   
        left++;
    }

    return result;
    }
}
上一篇:判断直线和圆的交点


下一篇:剑指offer 19.顺时针打印矩阵