顺转数组(JS实现)

顺转数组是什么?

语言描述不太好描述,但是举个例子你就懂。比如,数字5的顺转数组,如下:

1	2	3	4	5
16	17	18	19	6
15	24	25	20	7
14	23	22	21	8
13	12	11	10	9

如你所见,125构成了一个5*5的数组,且数组的构成像一个右螺旋,这个就叫数字5的顺转数组

那么问题来了?如何求一个数字的顺转数组?例如,这样的题目,输入一个数字n,请输出数字的顺转数组。

我们来分析一下


声明:以下思路来自个人想法,有更好的解法可以评论区指教

为了方便讲解,我们先上一张图,看下面:
在这里插入图片描述
我们可以看到,1->4行不变列逐渐增加,5->8列不变行逐渐增加,9->12行不变列逐渐减少,13->16列不变行逐渐减少,而且此时是以 4 也就是 (n-1) 为一个迭代,这是第一层。之后你会发现,第二层,第三层有同样的规律,直到到达最里面那一层。那我们如何确定遍历多少层呢?

这样去看,每迭代一层,也就是少了一圈,少了一圈其实厚度少了 2 (左右上下都已经遍历) ,所以遍历的层数是以差值为2的等差递减,也即第二层是以 2 也就是(n-3)为一个迭代的 , 当n递减到<0时,说明已经迭代到最后一层了,可以结束迭代 , 也即 (n+1)/2。

那我们这里其实仅仅需要三个关键变量即可 , i:表示行号 j:表示列号 t:记录当前层的迭代数。这样,我们只要迭代 (n+1)/2 次 ,且每次迭代4个边,每个边迭代t次,且到转折点时,切换行列变换,便可以将所有位置按照顺转数组的方式走一边。

JS的实现

const readline = require('readline');

const rl = readline.createInterface({
    input : process.stdin,
    output : process.stdout
});

rl.on('line',(input)=>{
    try {
        let n = parseInt(input);
        rl.close();
        (function(){
            let arr = new Array(n);
            for(let i=0;i<n;i++){
                arr[i] = new Array(n);
            }
            let t = n-1,m=1;
            let index  = {
                i : 0,
                j : 0
            } ;
            let comp = function(x , index){
                switch(x){
                    case 1 : index.j++;break;
                    case 2 : index.i++;break;
                    case 3 : index.j--;break;
                    case 4 : index.i--;break;
                }
            }
            while(t>=0){
                for(let x=1;x<=4;x++){
                    for(let y=0;y<t;y++){
                        arr[index.i][index.j] = m;
                        m++;
                        comp(x , index);
                    }
                }
                index.i++;
                index.j++;
                if(index.j == Math.floor(n/2) && index.i == Math.floor(n/2)){
                    arr[index.i][index.j] = m;
                    break;
                }
                t -= 2;
            }
            console.log(arr);
        })();
    } catch (error) {
        console.log(error);
    }
});
有问题可以评论区指出,我看到的话一定会回复的?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

angelavor

觉得有收获,给我个三连吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值