/**
* 转圈打印矩阵 要求额外空间复杂度为O(1)
* 1 2 3 4
* 5 6 7 8
* 9 10 11 12 矩阵转圈打印为: 1 2 3 4 8 12 11 10 9 5 6 7
*
*/
function spiralOrderPrint(martix) {
let tR = 0;
let tC = 0;
let dR = martix.length - 1;
let dC = martix[0].length - 1;
while(tR <= dR && tC <= dC) {
printEdge(martix, tR++, tC++, dR--, dC--) // tR++ tC++ 起始点转向下一个点 dR-- dC-- 最后一个点转向内圈,直到打印完所有的数
}
}
function printEdge(martix, tR, tC, dR, dC) {
if (tR === dR) {
for (let i = tC; i <= dC; i++) {
console.log(martix[tR][i] + " ");
}
} else if (tC === dC) {
for (let i = tR; i <= dR; i++) {
console.log(martix[i][tC] + " ");
}
} else {
let curC = tC;
let curR = tR;
while(curC !== dC) {
console.log(martix[tR][curC] + " ");
curC++;
}
while(curR !== dR) {
console.log(martix[curR][dC] + " ");
curR++;
}
while(curC !== tC) {
console.log(martix[dR][curC])
curC--;
}
while(curR !== tR) {
console.log(martix[curR][tC] + " ");
curR--;
}
}
}
let mar= [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
spiralOrderPrint(mar);
// 控制台输出 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
给定矩阵左上角的点和右下角的点的行号和列号,可以顺时针打印从左上角到右下角,再从右下角到左上角的整圈数据,之后左上角的点行号和列号递增,右下角的点行号和列号减一,就可以打印第二圈的数据。结束条件是左上角的行号或者列号有一个大于了右下角对应点的行号或者列号。
/**
* 给定一个整型正方形矩阵matrix,请把该矩阵调整成 顺时针旋转90度的样子。
* 【要求】 额外空间复杂度为O(1)。
*/
/**
* 给定一个整型正方形矩阵matrix,请把该矩阵调整成 顺时针旋转90度的样子。
* 【要求】 额外空间复杂度为O(1)。
*/
function rotate(martix) {
let tR = 0;
let tC = 0;
let dR = martix.length - 1;
let dC = martix[0].length - 1;
while(tR < dR) {
rotateEdge(martix, tR++, tC++, dR--, dC--);
}
}
function rotateEdge(martix, tR, tC, dR, dC) {
let times = dC - tC;
let temp = 0;
for (let i = 0; i !== times; i++) {
temp = martix[tR][tC + i];
martix[tR][tC+i] = martix[dR-i][tC];
martix[dR-i][tC] = martix[dR][dC-i];
martix[dR][dC-i] = martix[tR+i][dC];
martix[tR+i][dC] = temp;
}
}
function printMartix(martix) {
for (let i = 0; i !== martix.length; i++) {
for (let j = 0; j !== martix[0].length; j++) {
console.log(martix[i][j] + " ");
}
}
}
let mar = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];
printMartix(mar);
rotate(mar);
console.log("=============");
printMartix(mar);
/**
* 之字形打印矩阵数据
* 1 2 3 4
* 5 6 7 8 之字形打印为1 2 5 9 6 3 4 7 10 11 8 12
* 9 10 11 12
*
* 思路:在左上角的元素开始,有两个指针p1,p2一个一直往右,到最有后再往下,一个一直往下,到最下边后再往右,
* 两个指针连接的对角线就是每次要打印的数值;同时一个布尔常量控制是从左下往右上打印还是相反方向
*/
/**
* 之字形打印矩阵数据
* 1 2 3 4
* 5 6 7 8 之字形打印为1 2 5 9 6 3 4 7 10 11 8 12
* 9 10 11 12
*
* 思路:在左上角的元素开始,有两个指针p1,p2一个一直往右,到最有后再往下,一个一直往下,到最下边后再往右,
* 两个指针连接的对角线就是每次要打印的数值;同时一个布尔常量控制是从左下往右上打印还是相反方向
*/
function printMartixZigZig(martix) {
let tR = 0,
tC = 0,
dR = 0,
dC = 0;
let fromUp = false;
let endR = martix.length - 1;
let endC = martix[0].length - 1;
while (tR !== endR + 1) {
printLevel(martix, tR, tC, dR, dC, fromUp);
tR = tC === endC ? tR + 1 : tR;
tC = tC === endC ? tC : tC + 1; // 从左到右再往下
dC = dR === endR ? dC + 1 : dC; // 从上到下再往右
dR = dR === endR ? dR : dR + 1;
// dC 和 dR 的改变顺序不能调换
fromUp = !fromUp; // 改变打印的方向
}
}
// 打印对角线上的数据
function printLevel(m, tR, tC, dR, dC, tf) {
if (tf) {
while(tR !== dR + 1) {
// 右上向左下
console.log(m[tR++][tC--] + " ");
}
} else {
// 左下往右上打印
while(dR !== tR - 1) {
console.log(m[dR--][dC++] + " ");
}
}
}
let martix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]];
printMartixZigZig(martix);