构造一个螺旋的二维数组的思想,是完全可以应用到螺旋打印二维数组上面的;
这里只实现构造螺旋二维数组;
1. 要求如下,构造一个螺旋,即顺时针的二维数组
2. 思路说明
1. 首先我们按照要求螺旋思路去观察整个数组,假设数组为arr[i][j]
2. 可以发现从[0,0]到[4,2]的元素下标变化为,j先增加到最大,然后i增加到最大
3. 从[4,2]到[1,0]的元素下标变化为,j先减到最小,i再减到最小
4. 从[1,0]到[3,1]的元素下标变化为,j先增加到最大,然后i增加到最大
5. j和i的同时增加和减小都是从j开始的
现在总结下规律和解决思路 :
1. 从上面的观察可以看出,j和i都是依次增大,都增大到最大值以后,开始依次减小,然后再都减小到最小值,再开始依次增大...
2. 所以下面代码的实现中的if判断,我采取的解决方案就是,先让j开始增加,当j增加到一个临界点(越界或数组元素已经赋值,如[0,2]),再让i开始增加,当i增加到一个临界点时(越界或数组元素已经赋值,如[4,2]),这时候非常关键(else代码逻辑),j和i需要同时减小了
3. 最后就是非常关键的,解决j和i由同时增加变为同时减小的过程,其实增加和减小都可以看作为加法,所以这里实现统一改为加法即可(else代码逻辑)
4. 当j和i由同时增加变为减小的生活,j首先减小到[4,0],i再减小为[1,0]
5. 循环即完成构造螺旋二维数组
3. 代码实现
private static void printArrNew(int row, int col) {
// 初始化数组元素都为0,螺旋为数组元素赋值
int[][] arr = new int[row][col];
int number = 1;
// 此处是为了将螺旋过程中i,j的坐标转换,都转化为加法运算,+1,+(-1)
final int finalReverse = -1;
int reverse = finalReverse * finalReverse;
int i = 0;
int j = 0;
// 数组中的元素都赋值完成,退出循环
while (arr[i][j] == 0) {
arr[i][j] = number++;
// 前面两个判断,是判断数组按照螺旋规律,next元素是否赋值
if (j + reverse >= 0 && j + reverse < arr[i].length && arr[i][j + reverse] == 0) {
j += reverse;
} else if (i + reverse >= 0 && i + reverse < arr.length && arr[i + reverse][j] == 0) {
i += reverse;
} else {
// 螺旋到某一个节点,要进行坐标转换,此处的节点是i,j同时增加到最大,或者同时减小到最小
reverse *= finalReverse;
j += reverse;
}
}
System.out.println("======= 构造螺旋数组完成打印 =======");
print(arr);
}