力扣螺旋矩阵题解

题目

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

示例:

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

链接

力扣

关键点

  1. 四角边界的处理

  2. 条件的处理使当前结点处理还是下一节点处理

遵顼循环不变量原则

不变量即边界条件不变

左闭右开

一条线上有连个结点,该原则的处理方式为,处理第一个结点及边,第二个结点在处理第二条边时处理

实现的细节

  1. n为偶数。生成n*n维螺旋矩阵,需要旋转n/2圈(观察和推理所得)

  2. n为奇数。(n-1)/2圈,剩余一个元素直接放入螺旋中心,也可以视为(n+1)/2圈

  3. 每一圈的起始位置。不固定,定义起始坐标点(start x,start y),每一圈的起始位置都不一样

  4. 第三个结点(右下角),该点的列坐标无需赋初值,处理第二个点的列坐标可以直接用于第三个结点的处理

实现流程

  1. 定义起始点的坐标位置(startx,starty),遍历元素使用坐标(i,j)表示,圈数loop,更新缩圈后的边界offset

  2. while循环(条件是:圈数–)以圈为最小单位控制,四个for循环(条件是:j = starty; j < n - offset; j++)控制每条边上的元素

  3. 若n为奇数,n^2直接给矩阵中心赋值

流程分析

  1. 每一圈的开始的坐标由start控制,i,j只负责处理边

  2. 第二圈相比第一圈,第三圈相比第二圈,起始位置发生了变化,各个角的坐标也发生了变化,因此引入变量loop,offset分别控制圈数,每条边处理的边界坐标

C++

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0)); 
        int startx = 0, starty = 0; 
        int loop = n / 2; 
        int mid = n / 2; 
        int count = 1; 
        int offset = 1; 
        int i,j;
        while (loop --) {
            i = startx;
            j = starty;


            for (j = starty; j < n - offset; j++) {
                res[startx][j] = count++;
            }
          
            for (i = startx; i < n - offset; i++) {
                res[i][j] = count++;
            }
           
            for (; j > starty; j--) {
                res[i][j] = count++;
            }
            
            for (; i > startx; i--) {
                res[i][j] = count++;
            }

            
            startx++;
            starty++;

           
            offset += 1;
        }

       
        if (n % 2) {
            res[mid][mid] = count;
        }
        return res;
    }
};

Java

class Solution {
    public int[][] generateMatrix(int n) {
        int start=0;
        int res[][]=new int[n][n];
        int i,j;
        int count=1;
        int loop=0;

        //控制圈
        while(loop++<n/2){

            //上边,遵循左闭右开原则
            for(j=start;j<n-loop;j++){
                res[start][j]=count++;
            }

            //右边
            for(i=start;i<n-loop;i++){
                 res[i][j]=count++;
                
            }

            //下边
            for(;j>=loop;j--){
                res[i][j]=count++;
            }

             //左边
            for(;i>=loop;i--){
                 res[i][j]=count++;
            }
            start++;
        }

        //n为奇数时,最后一个元素赋给矩阵中心的位置
        if(n%2==1){
             res[n/2][n/2]=count;
        }
        return res;
    }
}

Java实现分析(与C++不同之处)

受语法限制,实现的思路有所不同

  1. loop初值为0

  2. 使用loop替代offset,引用一个变量控制两种行为

  3. 后两个for循环条件含由=,是因为C++是与start(while循环中初值为0)比较,Java中的for(;i>=loop;i–)(while循环中loop初值为1),所以判断条件为≥而非>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值