14.哀家要长脑子了!

 

目录

1.598. 区间加法 II - 力扣(LeetCode)

 2.419. 甲板上的战舰 - 力扣(LeetCode)

3.54. 螺旋矩阵 - 力扣(LeetCode)

4. 498. 对角线遍历 - 力扣(LeetCode)

 5. 566. 重塑矩阵 - 力扣(LeetCode)


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;
    }
};

 

  • 32
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值