顺转数组是什么?
语言描述不太好描述,但是举个例子你就懂。比如,数字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
如你所见,1
到25
构成了一个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);
}
});
有问题可以评论区指出,我看到的话一定会回复的?