数组
1. 旋转矩阵
题目:给定一幅由N × N矩阵表示的图像,其中每个像素的大小为4字节,编写一种方法,将图像旋转90度。不占用额外内存空间能否做到?
思路:
- 假设左上角矩阵元素为matrix[a] [b],右下角元素为matrix[c] [d]。
- 根据这两个对角元素,可以将矩阵的外圈进行旋转,matrix[a] [b]的值旋转到matrix[a] [d],matrix[c] [d]上的值选找到matrix[c] [b],…知道外圈交换完毕。
- 然后a++,b++,c–,d–。
- 还是以matrix[a] [b],matrix[c] [d]这两个对角元素构成的圈按上述操作进行旋转。直到a>c,旋转完毕。
public class RotateMatrix {
public static void rotate(int[][] matrix) {
//N为方形矩阵的行数
int N = matrix.length;
int a = 0;
int b = 0;
int c = N - 1;
int d = N - 1;
while(a < c){
for(int i = 0; i < d - b; i++){
swap(matrix, a, b, c, d, i);
}
a++;
b++;
c--;
d--;
}
}
public static void swap(int[][] matrix, int a, int b, int c, int d, int i){
int temp = matrix[a][b + i];
matrix[a][b + i] = matrix[c - i][b];
matrix[c - i][b] = matrix[c][d - i];
matrix[c][d - i] = matrix[a + i][d];
matrix[a + i][d] = temp;
}
public static void printMatrix(int[][] matrix){
int N = matrix.length;
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int[][] matrix = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
printMatrix(matrix);
System.out.println("--------");
rotate(matrix);
printMatrix(matrix);
}
}
2. *顺时针打印矩阵
思考:如何判断二维数组为空
题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]
思路:转圈就完事了,如下图所示
特殊情况:
-
二维数组为空
二维数组为空,要检查三个部分:
-
一是数组首地址是否为空
-
二是是否为{},也就是array.length==0的情况
-
三是是否为{{}},这时array.length=1,但是array[0].length==0。
所以判断语句为
if(array==null||array.length==0||(array.length==1&&array[0].length==0))
-
-
二维数组只有一行或一列
当二维数组为一行或一列时,只需一个for循环就行了,但是要注意等号
其代码如下,写得略微繁琐
public class ClockwisePrint {
public static int[] spiralOrder(int[][] matrix){
if(matrix==null||matrix.length==0||(matrix.length==1&&matrix[0].length==0)){
return new int[0];
}
//矩阵的行
int r = matrix.length;
//矩阵的列
int w = matrix[0].length;
//创建一个一维数组,用来存放顺时针打印的元素
int size = r * w;
int index = 0;
int[] arr = new int[size];
int a = 0;
int b = 0;
int c = r - 1;
int d = w - 1;
while(a <= c && b <= d){
if(a == c){
for(int i = 0; i <= d - b; i++){
arr[index++] = matrix[a][b + i];
}
}else if(b == d){
for(int i = 0; i <= c - a; i++){
arr[index++] = matrix[a + i][d];
}
}else{
for(int i = 0; i < d - b; i++){
arr[index++] = matrix[a][b + i];
}
for(int i = 0; i < c - a; i++){
arr[index++] = matrix[a + i][d];
}
for(int i = 0; i < d - b; i++){
arr[index++] = matrix[c][d - i];
}
for(int i = 0; i < c - a; i++){
arr[index++] = matrix[c - i][b];
}
}
a++;
b++;
c--;
d--;
}
return arr;
}
public static void main(String[] args) {
int[][] matrix = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
int[][] matrix2 = new int[][]{{1,2,3,4,5,6,7,8,9,10}};
int[] arr = spiralOrder(matrix2);
for(int value : arr){
System.out.print(value + " ");
}
}
}
3. 之字形打印矩阵
思路:
- 定义两点M,N,从(0,0)出发
- M每次向右移动1,右边没有数则向下移动
- N每次向下移动1,下边没有数则向右移动
- M N两点每一动一次,先读取MN这条对角线上的元素
public class Solution_ZPrintMatrix {
public static int[] function(int[][] matrix) {
//行数
int r = matrix.length;
//列数
int w = matrix[0].length;
//将之字形获取到的数存到arr数组中
int size = r * w;
int[] arr = new int[size];
//定义M(a,b),N(c,d)两点从(0,0)开始出发,
// M每次向右移动1,右边没有数则向下移动
// N每次向下移动1,下边没有数则向右移动
// M,N分别移动一次,从M到N可以画出一条对角线,
// 每次打印对角线上的元素即可。
int a = 0, b = 0, c = 0, d = 0;
arr[0] = matrix[0][0];
int j = 1;
//定义从对角线上获取元素的方向:true:从上到下;false:从下到上
boolean flag = true;
//当d==w或b==r时,所有元素遍历一遍
while (d < w) {
//规定M点的移动轨迹,先向右再向下
if (b < w) {
b++;
}
if(b == w){
b = w - 1;
a++;
}
//定义N点的移动轨迹,先向下再向右
if (c < r) {
c++;
}
if(c == r){
c = r - 1;
d++;
}
if(flag){
for (int i = 0; ; i++) {
if (b - i < 0 || a + i > r - 1) {
break;
}
arr[j++] = matrix[a + i][b - i];
}
flag = false;
}else{
for (int i = 0; ; i++) {
if (c - i < 0 || d + i > w - 1) {
break;
}
arr[j++] = matrix[c - i][d + i];
}
flag = true;
}
}
return arr;
}
public static void main(String[] args) {
int[][] matrix = new int[][]{{1,2,3,4},{4,5,6,7},{7,8,9,10}};
int[] arr = function(matrix);
for(int value : arr){
System.out.print(value + " ");
}
}
}
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)。
package array;
public class Solution_SearchNumInMatrix {
public static boolean function(int[][] matrix, int k){
//行
int r = matrix.length;
//列
int c = matrix[0].length;
//定义右上角起点坐标
int m = 0, n = c - 1;
while(m < r && n >= 0){
if(matrix[m][n] == k){
return true;
}else if(matrix[m][n] < k){
m++;
}else{
n--;
}
}
return false;
}
public static void main(String[] args) {
int[][] matrix = {{1,2,3,4},{2,2,3,5},{4,6,8,9}};
boolean result = function(matrix, 3);
System.out.println(result);
}
}