- 转圈打印矩阵
- 旋转正方形矩阵
- 之字形打印矩阵
- 在行跟列都排好序的矩阵中找数
1.转圈打印矩阵
给定一个整型矩阵matrix,请按照转圈的方式打印它。 例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 打印结果为:1,2,3,4,8,12,16,15,14,13,9, 5,6,7,11, 10 。
要求时间复杂度O(1)
思路:
- 找到矩阵左上角的位置和右下角的位置
- 按转圈的方向先打印最外层
- 对于最外层,要判断是否只有一行或者一列
- 打印完最外层,在打印里面的一层…重复步骤4
- 对于打印里面一层,要判断是否越界
public class sprialOrderPrint14 {
public static void main(String[] args) {
int[][] arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
sprialOrderPrint(arr);
}
public static void sprialOrderPrint(int[][] arr){
//左上行
int LeftTopRow = 0;
//左上列
int LeftTopColumn = 0;
//右下行 -> 二维矩阵的行数
int RightDownRow = arr.length - 1;
//右下列 -> 二维矩阵的列数
int RightDownColumn = arr[0].length - 1;
while (LeftTopRow <= RightDownRow && LeftTopColumn <= RightDownColumn){
printEdge(arr,LeftTopRow++,LeftTopColumn++,RightDownRow--,RightDownColumn--);
}
}
private static void printEdge(int[][] arr, int leftTopRow, int leftTopColumn, int rightDownRow, int rightDownColumn) {
//只有一行时
if (leftTopRow == rightDownRow){
for (int i = leftTopColumn;i <= rightDownColumn;i++){
System.out.println(arr[leftTopRow][i]);
}
}else if (leftTopColumn == rightDownColumn){
//还有一列时
for (int i = leftTopRow; i <= rightDownRow;i++){
System.out.println(arr[i][leftTopColumn]);
}
}else {
//还有多行多列时
//当前列
int curColumn = leftTopColumn;
//当前行
int curRow = leftTopRow;
while (curColumn != rightDownColumn){
System.out.println(arr[leftTopRow][curColumn++]);
}
while (curRow != rightDownRow){
System.out.println(arr[curRow++][curColumn]);
}
while (curColumn != leftTopColumn){
System.out.println(arr[curRow][curColumn--]);
}
while (curRow != leftTopRow){
System.out.println(arr[curRow--][curColumn]);
}
}
}
}
2.旋转正方形矩阵
要求
(1)给定一个整型正方形矩阵matrix,请把该矩阵调整成顺时针旋转90度的样子
(2)时间复杂度O(1)
思路:
(1)先旋转最外层矩阵,依次调换位置
(2)在旋转里层矩阵
public class Rorate15 {
public static void main(String[] args) {
int[][] arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
rorate(arr);
for (int i = 0;i <= arr.length - 1;i++){
for (int y = 0; y <= arr[0].length - 1;y++){
System.out.println(arr[i][y]);
}
}
}
public static void rorate(int [][] arr){
//左上行
int LeftTopRow = 0;
//左上列
int LeftTopColumn = 0;
//右下行 -> 二维矩阵的行数
int RightDownRow = arr.length - 1;
//右下列 -> 二维矩阵的列数
int RightDownColumn = arr[0].length - 1;
while (LeftTopRow <= RightDownRow){
rorateEdge(arr,LeftTopRow++,LeftTopColumn++,RightDownRow--,RightDownColumn--);
}
}
private static void rorateEdge(int[][] arr, int leftTopRow, int leftTopColumn, int rightDownRow, int rightDownColumn) {
//记录正方形一行/一列有几个元素
int times = rightDownColumn - leftTopColumn;
for (int i = 0; i < times; i++){
System.out.println("i" + i);
//左上 右上 交换
swap(arr,leftTopRow,leftTopColumn + i,leftTopRow + i,rightDownColumn);
//左上 右下 交换
swap(arr,leftTopRow,leftTopColumn + i,rightDownRow,rightDownColumn - i);
//左上 左下 交换
swap(arr,leftTopRow,leftTopColumn + i,rightDownRow - i,leftTopColumn);
}
}
private static void swap(int[][] arr, int leftTopRow, int leftTopColumn, int i, int leftTopColumn1) {
int tmp =arr[leftTopRow][leftTopColumn];
arr[leftTopRow][leftTopColumn] = arr[i][leftTopColumn1];
arr[i][leftTopColumn1] = tmp;
}
}
3.之字形打印矩阵
要求:额外空间复杂度为O(1)
思路:
用两个点作为标记点
对于A点,aC一直++,当aC = arr.length - 1时,aR开始++
对于B点,bR一直++。当bC = arr[0].length - 1时,bC开始++
//16.之字形打印矩阵
//要求:额外空间复杂度为O(1)
public class ZhiZagPrintMatrix17 {
public static void main(String[] args) {
int[][] arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12}};
zhiZagPrint(arr);
}
private static void zhiZagPrint(int [][] arr){
//A行
int aR = 0;
//A列
int aC = 0;
//B行
int bR = 0;
//B列
int bC = 0;
//标记最后一行下标
int endR = arr.length - 1;
//标记最后一列下标
int endC = arr[0].length - 1;
//判断从下往下打印还是从下往上打印
boolean fromUp = true;
//A行 != 最后一行 或者 B列 != 最后一列 打印结束
while (aR != arr.length){
print(arr,fromUp,aR,aC,bR,bC);
aR = aC == endC ? aR + 1: aR;
aC = aC == endC ? aC : aC + 1;
bC = bR == endR ? bC + 1: bC;
bR = bR == endR ? bR : bR + 1;
fromUp = !fromUp;
}
}
private static void print(int[][] arr, boolean fromUp, int aR, int aC, int bR, int bC) {
if (fromUp){
//从上往下打印
while (aR <= bR){
System.out.println(arr[aR++][aC--]);
}
}else {
//从下往上打印
while (bC <= aC){
System.out.println(arr[bR--][bC++]);
}
}
}
}
4.在行跟列都排好序的数组中找数
从最右上角的数开始找起
如果当前数cur > num,说明cur下边一列的数都>num,curC–;
如果当前数cur < num,说明cur左边一行的数都<num,curR++;
17.在行跟列都排好序的矩阵中找数
public class MatrixInContains17 {
public static void main(String[] args) {
int[][] arr = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12}};
Boolean contains = matrixInContains17(arr, 9);
if (contains){
System.out.println("true");
}else {
System.out.println("false");
}
}
private static Boolean matrixInContains17(int[][] arr,int num){
int curR = 0;
int curC = arr[0].length - 1;
Boolean contains = false;
int i = 0;
while (curC > -1 && curR < arr.length){
if (arr[curR][curC] < num){
//则这一列往下都不可能
curR++;
}else if (arr[curR][curC] > num){
//则左边一行都不可能
curC--;
}else if (arr[curR][curC] == num){
return true;
}
}
return contains;
}
}