73,题目:
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.
click to show follow up.
Follow up:
Did you use extra space?
A straight forward solution using O(mn) space is probably a bad idea.
A simple improvement uses O(m + n) space, but still not the best solution.
Could you devise a constant space solution?
本题是寻找一个矩阵中的0元素,然后将其行和列都置为0,in-place操作。我们需要考虑的就是如果直接更改会改变我们还未访问过的元素,对结果造成影响。所以一种简单而且效率较高的方式就是,分别使用两个数组以保存行和列是否应该被置为0,这样的空间复杂度为O(m+n),可以击败95%的用户,代码入下:
public void setZeroes(int[][] matrix) {
int[] row = new int[matrix.length];
int[] col = new int[matrix[0].length];
for(int i=0; i<matrix.length; i++)
for(int j=0; j<matrix[0].length; j++)
if(matrix[i][j] == 0) {
row[i] = 1;
col[j] = 1;
}
for(int i=0; i<matrix.length; i++){
if(row[i] == 1){
for(int j=0; j<matrix[0].length; j++)
matrix[i][j] = 0;
}
}
for(int i=0; i<matrix[0].length; i++){
if(col[i] == 1){
for(int j=0; j<matrix.length; j++)
matrix[j][i] = 0;
}
}
}
然后我们继续思考,有没有什么更好的方式可以节省空间复杂度呢,我们可以考虑使用矩阵的第一行和第一列来达到上面使用的row和col两个数组的作用,不过要使用另外两个boolean型的变量记录第一行和第一列是否应该被置为0。代码入下:
public void setZeroes1(int[][] matrix) {
boolean fr = false,fc = false;
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[0].length; j++) {
if(matrix[i][j] == 0) {
if(i == 0) fr = true;
if(j == 0) fc = true;
matrix[0][j] = 0;
matrix[i][0] = 0;
}
}
}
for(int i = 1; i < matrix.length; i++) {
for(int j = 1; j < matrix[0].length; j++) {
if(matrix[i][0] == 0 || matrix[0][j] == 0) {
matrix[i][j] = 0;
}
}
}
if(fr) {
for(int j = 0; j < matrix[0].length; j++) {
matrix[0][j] = 0;
}
}
if(fc) {
for(int i = 0; i < matrix.length; i++) {
matrix[i][0] = 0;
}
}
}
74,题目:
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.
For example,
Consider the following matrix:
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
Given target = 3, return true.
这道题是寻找矩阵中是否存在某一个元素,而且矩阵是递增形式。所以一种简单有效的方法就是遍历数组的行,用target和每行最后一个元素作比较,如果小于该元素,则遍历该行判断target是否存在其中,否则返回false。代码入下:
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0)
return false;
int n = matrix[0].length - 1;
for(int i=0; i<matrix.length; i++){
if(matrix[i][n] >= target){
for(int j=0; j<=n; j++){
if(matrix[i][j] == target)
return true;
}
break;
}
}
return false;
}
另外一种思路就是,将该矩阵当做是一个一维数组,这样我们就可以方便的使用二分搜索的方法找到元素是否存在与矩阵之中。代码入下:
public boolean searchMatrix1(int[][] matrix, int target) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0)
return false;
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;
}