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)。
思路:如果给出左上方的顶点的坐标A(tr,tl),和右下角的点B(dr,dl)
(top row,top line),(down row,down line),这样可以轻松实现打印最外面的所有数字,把这个过程封装成个函数,然后循环调用。
code
package exercise;
/*
转圈打印矩阵
*/
class MatCirclePrint {
private Integer[][] mat;
public MatCirclePrint(Integer[][] mat){
this.mat=mat;
}
public void CirclePrintmat(){
int tr=0,tl=0,dr=mat.length-1,dl=mat[0].length-1;
while (tr<=dr && tl<=dl){
printEdge( tr++, tl++, dr--, dl--);
}
}
public void printEdge(Integer tr,Integer tl,Integer dr,Integer dl){
//tr toprow,dr downrow;[tr,tl]最左上角1的坐标,[dr,dl]最右下角
if (tr==dr){//数据就一行
while (tl<=dl){
System.out.print(mat[0][tl]);
System.out.print(" ");
tl++;
}
}else if (tl==dl){//数据就一列
while (tr<=dr){
System.out.println(mat[tr][0]);
tr++;
}
}
else {
int curL=tl;//当前走到哪一列了
int curR=tr;//当前走到哪一行了
while(curL<dl){
System.out.print(mat[curR][curL]);
System.out.print(" ");
curL++;
}
while (curR<dr){
System.out.print(mat[curR][curL]);
System.out.print(" ");
curR++;
}
while (curL>tl){
System.out.print(mat[curR][curL]);
System.out.print(" ");
curL--;
}
while (curR>tr){
System.out.print(mat[curR][curL]);
System.out.print(" ");
curR--;
}
}
}
public static void main(String[] args) {
MatCirclePrint mcp1=new MatCirclePrint(new Integer[][]{{1,2,3,4}});
mcp1.printEdge(0,0,0,3);
System.out.println();
System.out.println("-------------分割线--------------------");
MatCirclePrint mcp2=new MatCirclePrint(new Integer[][]{{5},{6},{7},{8}});
mcp2.printEdge(0,0,3,0);
System.out.println("-------------分割线--------------------");
MatCirclePrint mcp3=new MatCirclePrint(new Integer[][]{{1, 2, 3, 4},
{5, 6, 7, 8},
{9,10,11,12},
{13,14,15,16}
});
System.out.println("printEdge函数测试!");
mcp3.printEdge(0,0,3,3);
System.out.println("");
System.out.println("-------------分割线--------------------");
System.out.println("测试CirclePrintmat()");
mcp3.CirclePrintmat();
}
}
2、旋转正方形矩阵
旋转正方形矩阵
【题目】 给定一个整型正方形矩阵matrix, 请把该矩阵调整成
顺时针旋转90度的样子。
【要求】 额外空间复杂度为O(1)
package exercise;
/*
转圈打印矩阵
*/
class Rotate {
public void rotate(int[][] matrix) {
int startR=0;
int startL=0;
int endR =matrix.length-1;
int endL =matrix[0].length-1;
while(startR<=endR){
rotedge(matrix,startR++,startL++,endR--,endL--);
}
}
public void rotedge(int[][]matrix,int topRow,int topLine,int downRow,int downLine ){
int tem=0;
int times=downLine-topLine;
for(int i=1;i<=times;i++){
tem=matrix[topRow][topLine+i];
matrix[topRow][topLine+i]=matrix[downRow-i][topLine];
matrix[downRow-i][topLine]=matrix[downRow][downLine-i];
matrix[downRow][downLine-i]=matrix[topLine+i][downLine];
matrix[topLine+i][downLine]=tem;
}
}
}
3、之” 字形打印矩阵
“之” 字形打印矩阵
【题目】 给定一个矩阵matrix, 按照“之” 字形的方式打印这
个矩阵, 例如:
1 2 3 4
5 6 7 8
9 10 11 12
“之” 字形打印的结果为: 1, 2, 5, 9, 6, 3, 4, 7, 10, 11,
8, 12
【要求】 额外空间复杂度为O(1)
思路:构建A,B两个点,A点一直右移,走到最右端下移;
B点一直下移,走到最下端右移;
一直打印A,B两点连线上的数据
代码如下:
package exercise;
class PrintZhiMat{
public void printZhimat(int[][]arr){
int tem_ar=0;
int tem_al=0;
int tem_br=0;
int tem_bl=0;
int count=0;
while (tem_ar!=arr.length ){
//循环终止条件,A来到最后一行
printdiagonal(arr,tem_ar,tem_al,tem_br,tem_bl,count%2);
//下面的判断写成三目运算符更好
if (tem_al<arr[0].length-1){
tem_al++;
}else {
tem_ar++;
}
if (tem_br<arr.length-1){
tem_br++;
}
else {
tem_bl++;
}
count++;
//System.out.printf("这是第%d次循环",count++);
}
}
public void printdiagonal(int[][] arr,int ar,int al,int br,int bl,int flag){
//A(ar,al),B(br,bl)
int tem_ar=ar;
int tem_al=al;
int tem_br=br;
int tem_bl=bl;
if (flag==0){
while (tem_ar<=tem_br){
System.out.print(arr[tem_br--][tem_bl++]);
System.out.print(" ");
}
}
if (flag==1){
while (tem_ar<=tem_br){
System.out.print(arr[tem_ar++][tem_al--]);
System.out.print(" ");
}
}
}
public static void main(String[] args) {
int[][] mat=new int[][]{{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,16} };
PrintZhiMat pzt =new PrintZhiMat();
pzt.printdiagonal(mat,0,3,3,0,0);
System.out.println("\n----------------分割线-----------------");
pzt.printdiagonal(mat,0,3,3,0,1);
System.out.println("\n----------------分割线-----------------");
pzt.printZhimat(mat);
}
}
执行结果
13 10 7 4
----------------分割线------------------------
4 7 10 13
----------------分割线------------------------
1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16
4 在已排好序的矩阵中查找数字
【题目】 给定一个有N*M的整型矩阵matrix和一个整数K,matrix的每一行和每一 列都是排好序的。 实现一个函数, 判断K是否在matrix中。 例如:
0 1 2 5
2 3 4 7
4 4 4 8
5 7 7 9
如果K为7, 返回true; 如果K为6, 返回false。
【要求】 时间复杂度为O(N+M), 额外空间复杂度为O(1)
思路:
选取左下角(或右上角)的点mat[mat.length-1][0]作为起点;
当前的数比K小则向右走;
当前的数比K大则向上走;
临界条件,遍历的数走出mat
public class e8_findNumOrdered {
public boolean findNumOrdered(int[][] mat, int K){
int i=mat.length-1,j=0;
while (i<mat.length && j<mat[0].length){
if (mat[i][j]==K){
return true;
}
else if (mat[i][j]>K){
i--;
}else {
j++;
}
}
return false;
}
public static void main(String[] args) {
int [][]arr={
{1,3,5,7,9},
{3,4,6,17,10},
{9,11,12,20,35},
{40,41,56,70,100}
};
e8_findNumOrdered fno=new e8_findNumOrdered ();
System.out.println(fno.findNumOrdered(arr,9));
}
}