Problem 73. Set Matrix Zeroes
-
题目描述
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.Example:
Input: [ [0,1,2,0], [3,4,5,2], [1,3,1,5] ] Output: [ [0,0,0,0], [0,4,5,0], [0,3,1,0] ]
-
解题思路
考虑到在程序运行时我们能申请的额外内存空间只能为O(1),所以我们只能对传入的矩阵 matrix 本身进行操作,算法原理如下:- 遍历矩阵 matrix。利用 matrix 的第一行和第一列作为标记,即如果 matrix[3][4] = 0,那么我们就把 matrix[0][4] 和 matrix[3][0] 置为0,表示第3+1行和第4+1列最后都要置为0。
- 再次遍历矩阵 matrix,如果 matrix[i][0] = 0或者matrix[0][j] = 0,则把所有的 matrix[i][j] 都置为0。
需要注意的一点是,在第一次遍历时,由于将 matrix[i][0] 或者 matrix[0][j] 置为0,会改变 matrix[i][0] 或者 matrix[0][j] 本身。举个例子,如果矩阵 matrix 只有 matrix[3][4] = 0,那我们就要将 matrix[0][4] 和 matrix[3][0] 置为0。在第二次遍历时,由于在第一行和第一列发现了0,所以会将第一行和第一列都置为0,而实际上我们只需要对第3+1行和第4+1列置为0,这显然不是正确的结果。
所以,我们需要引入两个新的 bool 变量 rowZero 和 colZero,用来判断第一行和第一列在初始的时候有没有0。并且在后续遍历的过程中,从 i=1 和 j=1 开始遍历。
-
代码实现
class Solution {
public:
void setZeroes(vector<vector<int> >& matrix) {
int row = matrix.size();
if (row == 0)
return ;
int col = matrix[0].size();
if (col == 0)
return ;
bool rowZero = false, colZero = false;
for(int i = 0; i < col; ++i){
if(matrix[0][i] == 0){
rowZero = true;
break;
}
}
for(int j = 0; j < row; ++j){
if(matrix[j][0] == 0){
colZero = true;
break;
}
}
for(int i = 1; i < row; ++i){
for(int j = 1; j < col; ++j){
if(matrix[i][j] == 0){
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
for(int i = 1; i < row; ++i)
for(int j = 1; j < col; ++j)
if(matrix[i][0] == 0 || matrix[0][j] == 0)
matrix[i][j] = 0;
if(rowZero)
for(int i = 0; i < col; ++i)
matrix[0][i] = 0;
if(colZero)
for(int j = 0; j < row; ++j)
matrix[j][0] = 0;
}
};
Problem 75. Sort Colors
-
题目描述
Given an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white and blue.Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.
Note: You are not suppose to use the library’s sort function for this problem.
Example:
Input: [2,0,2,1,1,0] Output: [0,0,1,1,2,2]
-
解题思路
由于题目要求只能遍历nums一次,所以我们可以定义两个指针red和blue,其中red指向首元素,blue指向末元素。在对nums进行遍历的时候,遇到0就交换到red的位置,遇到2就交换到blue的位置,遇到1则跳过。如此一来,在遍历过之后,0全在左边,2全在右边,1留在了中间。
算法如下:
- 若nums[i] == 0,则将nums[i]和nums[red]交换,随后i和red分别指向下一位;
- 若nums[i] == 1,则跳过交换操作,即直接将i指向下一位;
- 若nums[i] == 2,则将nums[i]和nums[blue]交换,再将blue指向前一位即可,i不能指向下一位(因为i是从头开始遍历的,且当遇到2就被交换到后面,所以nums[i]和nums[red]交换后,nums[i]得到的只能是1;而nums[i]和nums[blue]交换后,nums[i]得到的可能是1或者0,所以i需要停在原位继续判断)。
- 代码实现
class Solution {
public:
void sortColors(vector<int>& nums) {
int red = 0, blue = nums.size() -1;
int i = 0;
while(i <= blue){
if(nums[i] == 0){
int temp = nums[i];
nums[i] = nums[red];
nums[red] = temp;
red++;
i++;
}
else if(nums[i] == 1)
i++;
else{
int temp = nums[i];
nums[i] = nums[blue];
nums[blue] = temp;
blue--;
}
}
}
};