矩阵相关题目

顺时针打印矩阵

/**
 * @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("没有该数");
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值