顺时针打印矩阵
/**
* @param matrix 矩阵本身
* @param LR 左上角的行标
* @param LC 左上角的列标
* @param RR 右上角的行标
* @param RC 右上角的列标
*/
public static void printEdge(int[][]matrix, int LR, int LC, int RR, int RC) {
/**
* 如果不是方阵,那么可能会出现这种棒状结构
* LR == RR 和 LC == RC两种情况
* 如果处于同一行,则从打印这一行即可。
*/
if(LR == RR) {
for(int c = LC; c <= RC; c++) {
System.out.print(matrix[LR][c] + " ");
}
}else if(LC == RC) {
//同一列
for(int r = LR; r <= RR; r++) {
System.out.print(matrix[r][LC] + " ");
}
}else {
//如果两个点不在同一行和同一列,转圈打印一层信息
int curR = LR;
int curC = LC;
while(curC != RC) {
System.out.print(matrix[curR][curC++] + " ");
}
while(curR != RR) {
System.out.print(matrix[curR++][curC] + " ");
}
while(curC != LC) {
System.out.print(matrix[curR][curC--] + " ");
}
while(curR != LR) {
System.out.print(matrix[curR--][curC] + " ");
}
}
}
public static void spiralOrderPrint(int matrix[][]) {
int LR = 0;
int LC = 0;
int RR = matrix.length - 1;
int RC = matrix[0].length - 1;
//层层递进
while(LR <= RR && LC <= RC) {
printEdge(matrix, LR++, LC++, RR--, RC--);
}
}
private static int startNum = 1;
public static void createEdge(int[][]matrix, int LR, int LC, int RR, int RC) {
//如果方阵是 奇数*奇数 的,那么会出现这种情况。
if(LR == RR && LC == RC) {
matrix[LR][LC] = startNum;
}else {
//不同行不同列
int curR = RR;
int curC = RC;
while(curR < LR) {
matrix[curR++][RC] = startNum++;
}
while(curC > LC) {
matrix[curR][curC--] = startNum++;
}
while(curR > RR) {
matrix[curR--][curC] = startNum++;
}
while(curC < RC) {
matrix[curR][curC++] = startNum++;
}
}
}
public static int[][] createMatrix(int n) {
int[][] matrix = new int[n][n];
int RR = 0;
int RC = n - 1;
int LR = n - 1;
int LC = 0;
while(RR <= LR && RC >= LC) {
createEdge(matrix, LR--, LC++, RR++, RC--);
}
return matrix;
}
方阵顺时针旋转90°
/**
* 顺时针旋转一层
* @param matrix 方阵
* @param LR 左上角的行标
* @param LC 左上角的列标
* @param RR 右上角的行标
* @param RC 右上角的列标
*/
public static void rotateEdge(int[][] matrix, int LR, int LC, int RR, int RC) {
int times = RC - LC;
int tmp = 0;
for(int i = 0; i < times; i++) {
//此处根据图来体会点坐标的变化
tmp = matrix[LR][LC + i];
matrix[LR][LC + i] = matrix[RR - i][LC];
matrix[RR - i][LC] = matrix[RR][RC - i];
matrix[RR][RC - i] = matrix[LR + i][RC];
matrix[LR + i][RC] = tmp;
}
}
public static void rotate(int[][] matrix) {
int LR = 0;
int LC = 0;
int RR = matrix.length - 1;
int RC = matrix[0].length - 1;
//此处默认是方阵结构,故当LR == RR时就是旋转的中心点,即无需处理
while(LR < RR) {
rotateEdge(matrix, LR++, LC++, RR--, RC--);
}
}
之字形打印矩阵
public static void sawtoothPrint(int[][] matrix) {
int aR = 0;
int aC = 0;
int bR = 0;
int bC = 0;
int endR = matrix.length - 1;
int endC = matrix[0].length - 1;
boolean flag = false;
//终止条件:A点来到最后一行(或者B点来到最后一列)这两个点是同一个时刻来到边界的
while(aR <= endR) {
printLevel(matrix, aR, aC, bR, bC, flag);
flag = !flag;
/**
* 设定A点的移动轨迹
* 这里需要先更新行坐标,因为如果先更新列的话aC可能会+1,则影响判断
* A的行坐标:如果A点已经触碰到右边界,则向下移动(行坐标+1),否则行坐标不变
* A的列左边:如果A点已经触碰到右边界,则列坐标不变,否则向右移动(列坐标+1)
*/
aR = aC == endC ? aR + 1 : aR;
aC = aC == endC ? aC : aC + 1;
/**
* 设定B点的移动轨迹
* 这里需要先更新列坐标,因为如果先更新行的话bR可能会+1,则影响判断
* B的列坐标:如果B点已经触碰到下边界,则向右移动(列坐标+1),否则列坐标不变
* B的行坐标:如果B点已经触碰到下边界,则行坐标不变,否则向下移动(行坐标+1)
*/
bC = bR == endR ? bC + 1 : bC;
bR = bR == endR ? bR : bR + 1;
}
}
public static void printLevel(int[][] matrix, int aR, int aC, int bR, int bC, boolean flag) {
//给定两个点,打印一条对角线
if(flag) {
//A点向B点走
while(aR <= bR) {
System.out.print(matrix[aR++][aC--] + "\t");
}
}else {
//B点向A点走
while(bR >= aR) {
System.out.print(matrix[bR--][bC++] + "\t");
}
}
}
在行列都排好序的矩阵中找数
public static void searchNum(int[][] matrix, int targetNum) {
int curR = 0;
int curC = matrix[0].length - 1;
int curNum;
while(curR < matrix.length && curC < matrix[0].length) {
curNum = matrix[curR][curC];
if(curNum == targetNum) {
System.out.println("找到 (" + targetNum + ") 的坐标为:" + "[" + curR + ", " + curC +"]");
return;
}else if(curNum > targetNum) {
curC--;
}else {
curR++;
}
}
System.out.println("没有该数");
}