【LeetCode】矩阵系列

54. Spiral Matrix

题目:螺旋打印一个矩阵

思路:设置四个标志位,分别表示行范围和列范围,每打印一条,范围缩小1,注意要判断超范围。

public class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> ret = new ArrayList<>();
        if(matrix.length == 0 || matrix[0].length == 0) return ret;
        int flag = 1;
        int rowend = matrix.length-1, colend = matrix[0].length-1;
        int rowstart = 0, colstart = 0;
        while(rowstart <= rowend && colstart <= colend){
            if(colstart <= colend){
                for(int i = colstart; i <= colend; i++){
                    ret.add(matrix[rowstart][i]);
                }
            }
            rowstart++;
            if(rowstart>rowend || colstart>colend) break;
            if(rowstart <= rowend){
                for(int i = rowstart; i <= rowend; i++){
                    ret.add(matrix[i][colend]);
                }
            }
            colend--;
            if(rowstart>rowend || colstart>colend) break;
            if(colstart <= colend){
                for(int i = colend; i >= colstart; i--){
                    ret.add(matrix[rowend][i]);
                }
            }
            rowend--;
            if(rowstart>rowend || colstart>colend) break;
            if(rowstart <= rowend){
                for(int i = rowend; i >= rowstart; i--){
                    ret.add(matrix[i][colstart]);
                }
            }
            colstart++;
            if(rowstart>rowend || colstart>colend) break;
        }
        return ret;
    }
}

59. Spiral Matrix II

题目:用螺旋矩阵输出1到n*n

思路:与54完全一样

public class Solution {
    public int[][] generateMatrix(int n) {
        int[][] ret = new int[n][n];
        int rowend = n-1, colend = n-1;
        int rowstart = 0, colstart = 0;
        int count = 1;
        while(rowstart <= rowend && colstart <= colend){
            if(colstart <= colend){
                for(int i = colstart; i <= colend; i++){
                    ret[rowstart][i] = count++;
                }
            }
            rowstart++;
            if(rowstart <= rowend){
                for(int i = rowstart; i <= rowend; i++){
                    ret[i][colend] = count++;
                }
            }
            colend--;
            if(colstart <= colend){
                for(int i = colend; i >= colstart; i--){
                    ret[rowend][i] = count++;
                }
            }
            rowend--;
            if(rowstart <= rowend){
                for(int i = rowend; i >= rowstart; i--){
                    ret[i][colstart] = count++;
                }
            }
            colstart++;
        }
        return ret;
    }
}

73. Set Matrix Zeroes

题目:矩阵中零的位置,使该行和该列都置为零

思路:空间复杂度O(M+N)的方法

public class Solution {
    public void setZeroes(int[][] matrix) {
        int row = matrix.length;
        int col = matrix[0].length;
        int[] flag_r = new int[row];
        int[] flag_c = new int[col];
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                if(matrix[i][j] == 0){
                    flag_r[i] = 1;
                    flag_c[j] = 1;
                }
            }
        }
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                if(flag_r[i] == 1 || flag_c[j] == 1) matrix[i][j] = 0;
            }
        }
        return;
    }
}

O(1)空间复杂度的方法,实际就是把行标记和列标记放在第一行和第一列,最后单独做第一行和第一列的置零操作。

 public class Solution {
 public void setZeroes(int[][] matrix) {
     if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
     int m = matrix.length, n = matrix[0].length;
     boolean row = false, col = false;
     for (int i = 0; i < m; i++)
         for (int j = 0; j < n; j++){
             if (matrix[i][j] == 0) {
                 matrix[0][j] = 0;
                 matrix[i][0] = 0;
                 if (i == 0) row = true;
                 if (j == 0) col = true;
             }
         }
     for (int i = 1; i < m; i++){
         if (matrix[i][0] == 0){
             for (int j = 1; j < n;j++)
                 matrix[i][j] = 0;
         }
     }
     for (int j = 1; j < n; j++){
         if (matrix[0][j] == 0){
             for (int i = 1; i < m; i++)
                 matrix[i][j] = 0;
         }
     }
     if (row){
         for (int j = 0; j < n; j++)
             matrix[0][j] = 0;
     }
     if (col){
         for(int i = 0; i < m; i++)
             matrix[i][0] = 0;
     }
 }

74. Search a 2D Matrix 

题目:在一个行有序且每行最后一位小于下一行第一位的矩阵中找到目标值

思路:两次二分查找,一次找行值,一次找列值,思路简单,但是代码比较复杂

public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix.length == 0 || matrix[0].length == 0 || matrix[0][0] > target) return false;
        int m = matrix.length;
        int n = matrix[0].length;
        int start = 0, end = m-1;
        while(start <= end){
            int mid = start+(end-start)/2;
            if(matrix[mid][0] == target) return true;
            else if(matrix[mid][0] > target){
                end = mid-1;
            }
            else{
                start = mid+1;
            }
        }
        int p = end;
        start = 0;
        end = n-1;
        while(start <= end){
            int mid = start+(end-start)/2;
            if(matrix[p][mid] == target) return true;
            else if(matrix[p][mid] > target){
                end = mid-1;
            }
            else{
                start = mid+1;
            }
        }
        return false;
    }
}

将矩阵看成一个有序的一维向量,最开始的想法,但是没这么做

public boolean searchMatrix(int[][] matrix, int target) {
	
	int row_num = matrix.length;
	int col_num = matrix[0].length;
	
	int begin = 0, end = row_num * col_num - 1;
	
	while(begin <= end){
		int mid = (begin + end) / 2;
		int mid_value = matrix[mid/col_num][mid%col_num];
		
		if( mid_value == target){
			return true;
		
		}else if(mid_value < target){
			//Should move a bit further, otherwise dead loop.
			begin = mid+1;
		}else{
			end = mid-1;
		}
	}
	
	return false;
}

240. Search a 2D Matrix II 

题目:行有序且列有序,找目标值

思路:从右上角出发,大于目标值向下走,小于目标值向左走

public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix.length == 0 || matrix[0].length == 0) return false;
        int m = matrix.length;
        int n = matrix[0].length;
        if(matrix[0][0] > target || matrix[m-1][n-1] < target) return false;
        int row = 0, col = n-1;
        while(row < m && col >= 0){
            if(matrix[row][col] == target) return true;
            else if(matrix[row][col] > target) col--;
            else row++;
        }
        return false;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值