目录
1.598. 区间加法 II - 力扣(LeetCode)
哎哟我去我还想着模拟呢 模拟啥啊你模拟!
要抽象出事情问题的核心与本质啊。。。
所有格子的初始化状态都为0,那么经过几个数组的不断操作,最后最大的部分肯定是他们相交的部分
class Solution {
public:
int maxCount(int m, int n, vector<vector<int>>& ops) {
int k = ops.size();
int minx = m, miny = n;
for(int i = 0; i < k; i++){
minx = min(minx, ops[i][0]);
miny = min(miny, ops[i][1]);
}
return minx * miny;
}
};
2.419. 甲板上的战舰 - 力扣(LeetCode)
一看到这个题我就想到dfs但是我又不知道怎么去实现,对自己无语死了TAT
官方题解给出了两种方法:
方法一:遍历扫描
当遇到X的时候,就把X变成. 然后把X身边的X也变成. 怎么变,垂直方向:从它的右边开始(k=i+1)遍历到矩阵边界,我说为什么不从左边,因为它是一遇到X就开始这种操作,那么一遇到的肯定就是最左边。水平方向:从它的下面一个开始遍历到矩阵边界都是X的都变成.;一个位置的X操作完后计数加1。
class Solution {
public:
int countBattleships(vector<vector<char>>& board) {
int m = board.size(), n = board[0].size();
int count = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(board[i][j] == 'X'){
board[i][j] = '.';
for(int k = i + 1; k < m && board[k][j] == 'X'){
board[k][j] = '.';
}
for(int k = j + 1; k < n && board[i][k] == 'X'){
board[i][k] = '.';
}
count++;
}
}
}
return count;
}
};
方法二:枚举起点,一坨X只代表一艘军舰,就计算一次,如果发现是上一艘军舰的一部分就跳过
class Solution {
public:
int countBattleships(vector<vector<char>>& board) {
int m = board.size(), n = board[0].size();
int count = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(board[i][j] == 'X'){
if(i > 0 && board[i-1][j] == 'X'){
continue;
}
if(i > 0 && board[i-1][j] == 'X'){
continue;
}
count++;
}
}
}
return count;
}
};
i > 0 && board[i-1][j] == 'X'
这个是垂直方向的判断,意思就是:当这个位置是X并且旁边有地方可以判断时,就判断一下,如果它上面是X说明这个军舰是上一艘军舰的延续部分,已经被计算过了不用再计算,跳过。
3.54. 螺旋矩阵 - 力扣(LeetCode)
哎哟我去,这个我想用卡哥的方法,就是搞不好,我真的啊啊啊啊啊啊啊啊啊
然后看到题解里里面一个大神可巧妙的方法,不断移动上下左右边界。怎么个四呢?比如有上下左右四个边界。上边界小于下边界,左边界小于右边界。不断地移动边界来遍历矩阵,如果边界不满足以上条件即边界相交,遍历完毕。比如。遍历完第一排之后,第一排就可以删除了,体现在代码中就是(++u > d)既移动了边界又判断了是否遍历完毕。
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
int u = 0, d = m - 1;
int l = 0, r = n - 1;
vector<int>> res;
while(true){
for(int i = l; i < n; i++)
res.push_back(matrix[u][i])
if(++u > d) break;
for(int i = u; i < m; i++)
res.push_back(matrix[i][r]);
if(--r < l) break;
for(int i = r; i >= 0; i--)
res.push_back(matrix[d][i]);
if(--d < u) break;
for(int i = d; i >= 0; i++)
res.push_back(matrix[i][l]);
if(++l > r) break;
}
return res;
}
};
4. 498. 对角线遍历 - 力扣(LeetCode)
.
首先,一个 m x n的矩阵有m+n-2条对角线,为什么呢?因为第一个元素向左可以走m-1格,向下可以走n-1格。所以说对于一个左上角的元素有m-1次向左的机会,有n-1次向下的机会。合计m-n+2次机会,但是包括起点自身,所以只有m+n-1条对角线。
然后,每个对角线的起点:从0开始给对角线编号:会发现,第i条对角线
i为奇数,从右上往左下遍历
小于n时,对角线起点是从第一行的某一列开始,起点横坐标:0,纵坐标:i
大于n时,对角线起点是最后一列的某一行开始,起点横坐标:i-n+1 纵坐标:n-1
i为偶数,从左下往右上遍历
小于n时,对角线的起点是从第一列的某一行开始,起点横坐标:i,纵坐标:0
大于n时,对角线的起点是从最后一行的某一列开始,起点横坐标:m-1 纵坐标:i-m+1
最后往上走往下走不断遍历就好啦
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
int m = mat.size();
int n = mat[0].size();
vector<int> res;
for(int i = 0; i < m + n - 1; i++){
if(i % 2){
int x = i < n ? 0 : i - n + 1;
int y = i < n ? i : n - 1;
while(x < m && y >= 0){
res.push_back(mat[x][y]);
x++;
y--;
}
}
else{
int x = i < m ? i : m-1;
int y = i < m ? 0 : i - m + 1;
while(x >= 0 && y < n){
res.push_back(mat[x][y]);
x--;
y++;
}
}
}
return res;
}
};
5. 566. 重塑矩阵 - 力扣(LeetCode)
将一个m x n的矩阵变成 r x c的
对于一个m x n的矩阵来说:其索引和其在二维数组的位置映射关系如下
(i, j) ---> i * n + j
有一个元素位置是x(按行优先数到是第x位置, 想把它从m x n 放到 r x c的可不就是:
行号:x / c(一行有c个,放在哪一行了) 列号:x % c
class Solution {
public:
vector<vector<int>> matrixReshape(vector<vector<int>>& mat, int r, int c) {
int m = mat.size();
int n = mat[0].size();
vector<vector<int>> res(r, vector<int>(c));
if(m*n != r*c)
return mat;
for(int i = 0; i < m * n; i++){
res[i/c][i%c] = mat[i/n][i%n];
}
return res;
}
};