java解决螺旋矩阵leetcode第59题

48 篇文章 0 订阅
8 篇文章 0 订阅

一、问题描述

螺旋矩阵 II

CategoryDifficultyLikesDislikes
algorithmsMedium (77.37%)618-
Tags Companies

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

示例 1:

img

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

示例 2:

输入:n = 1
输出:[[1]]

提示:

  • 1 <= n <= 20

二、xin麒的思路

1、摘要:

​ 该题主要是涉及边界的问题,同时考察对编程的熟练程度(占比也不大),本题应用到作者的方法论有:观察法(通过观察得到规律)、特定代入法(使用几个典型的模型代入,构造出代入的模型的解决框架,再详细分析完善各种特殊的情况)

2、前提引入:

  • 每次都将num变量赋值给遍历到的数组元素,并且每次num都会自增;
  • end = nstart = 0分别作两边界的初始化;
  • 第**(first + 1)行 第(second + 1)列的数组元素为nums[first][second]**;

3、分析:

​ 通过观察,发现矩阵有三个转折点,分别为左上角右下角左下角,我们知道,那么状态改变时(进行转折)这三处很有可能会做出一些变化。我们可以取当n=3的情况进行分析:

  • 3.1.1指针一直往走:当在第一行遍历时,second不断增加,直到second等于end - 1时,便达到临界状态,那么循环退出条件必然包括second < end
  • 停顿下思考 --> 需要将second调整为end - 1,保持second在最后一列;同时我们希望下一次修改数组元素时是可以在下一个元素开始,于是需要将first + 1
  • 3.1.2指针一直往走:first不断增加,当向下走到尽头时,便是first等于end-1时的临界状态,循环退出条件必然包括first < end
  • 我们停顿下思考 --> 我们需要将first保持为end - 1 ,同时我们希望下一次修改数组元素时是可以在下一个元素开始,于是需要将second - 1;另外考虑到如果再有1向下走的情况,那么end应该是需要减小了,于是需要end - 1
  • 3.1.3指针一直往走,当向左时,second不断减小,当减小到second等于start时,便到达临界状态。循环退出条件必然包括second >= start
  • 停顿下思考 --> 我们希望接下来可以向上转折,那么需要将second保持为start;同时我们希望下一次修改数组元素时是可以在下一个元素开始,于是需要将first - 1
  • 因为向左走时,该层循环左边界start等于0,那么下次继续左走时,左边界应该向右收索,那么需要start+1(也因为向上走时上边界是start+1,这样修改也符合);
  • 3.1.4当一直向上走,当走到坐标(1,0)的位置,修改好元素时便退出,那么循环退出条件必然包括first >= start

  • 3.2此后外部循环继续,重新定义first = start,second = start,也就是说每一次外层循环开始时都是从左上角到右下角的对角线对应的元素开始的,符合;

  • 3.3外层循环的退出条件的思考:我们可以看数组元素的不断修改的过程,如果数组的最后一个数被修改了,会是什么情况呢?是数组元素被值为n*n的num变量赋值了。但是由于num是一个不断增长的数,那么我们可以使用num != n*n + 1来作为最外层的循环的循环条件

  • 而内层有4个并行的循环,防止num为n*n + 1时会进入这些内层循环,于是再在内层循环条件里并上一个和外层循环一样的条件。

三、xin麒的题解

class Solution {
    public int[][] generateMatrix(int n) {
        int num = 1;
        int end = n;
        int start = 0;
        int[][] nums = new int[n][n];
        int finalnum = n * n + 1;
        int first = 0;
        int second = 0;
        while (num != finalnum){
            first = start;
            second = start;

            while (second < end && num != finalnum){//往右
                nums[first][second++] = num++;
            }
            second--;//上述循环second退出了边界,需要补回
            first++;

            while (first < end && num != finalnum){//往下
                nums[first++][second] = num++;
            }
            first--;//上述循环first退出了边界,需要补回
            second--;
            end--;//这时右边界向左收缩

            while (second >= start && num != finalnum){//往左
                nums[first][second--] = num++;
            }
            second++;//上述循环second退出了边界,需要补回
            start++;//左边界向右收缩
            first--;

            while (first >= start && num != finalnum){//往上
                nums[first--][second] = num++;
            }
        }
        return nums;
    }
}
运行:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值