栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

英雄算法6月11号

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

英雄算法6月11号

01.08
class Solution {
    void change(vector>& matrix,int& rowSize, int& colSize, int r, int c){
        //change col
        int m_r = r, m_c = c;
        for(m_r = 0; m_r < rowSize; ++m_r){
            matrix[m_r][c] = 0;
        }
        //change row
        for(m_c = 0; m_c < colSize; ++m_c){
            matrix[r][m_c] = 0;
        }

    }
public:
    void setZeroes(vector>& matrix) {
        int rowSize = matrix.size(), colSize = matrix[0].size();
        int r = 0, c = 0;
        vector> rc;
        for(r = 0; r < rowSize; ++r){//遍历数组,寻找等于0的点
            for(c = 0; c < colSize; ++c){
                if(matrix[r][c] == 0){
                    rc.emplace_back(r,c);//记录所有0点
                }
            }
        }
    
        for(auto x: rc){
            change(matrix, rowSize, colSize, x.first, x.second);//统一更改所有0所在点的行列
        }
    }
};

没啥好说的

1727
class Solution {
public:
    int largestSubmatrix(vector>& matrix) {
        int rowSize = matrix.size(), colSize = matrix[0].size(); 
        int row = 0, col = 0, sum = 0;
        vector vline(colSize,0);

        for(row = 0; row < rowSize; ++row){//遍历每一行
            for(col = 0; col < colSize; ++col){//遍历每一列        
                if(matrix[row][col] == 1){//记录当前高度
                    ++vline[col];
                }
                else{
                    vline[col] = 0;
                }
            }

            vector tvline = vline;//使用备用数组,进行排序计算

            sort(tvline.begin(), tvline.end(),[](int x, int y){
                return x>y;
            });//降序排序

            for(int x = 0; x < tvline.size(); ++x){//确定最大面积
                sum = max((tvline[x]*(x+1)),sum);
            }
        }

        return sum;
    }
};

思路

以矩阵每一行为起点,向上计算连续1的个数,及求出每个一的最大高度。然后进行排序,求出最大面积。

1034

1.循环的方式深度优先搜索

class Solution {
public:
  vector> colorBorder(vector>& grid, int row, int col, int color) {
    vector> Node;//存储需要遍历的节点,row,col,color                                                              
    vector> visited(grid.size(),vector(grid[0].size(),false));//下一个节点是否被访问
    vector> target;//目标染色点的坐标
    vector dir = {-1,0,1,0,-1};//确定方向

    vector tmp = {row, col, grid[row][col]};
    Node.emplace_back(tmp);//存入初始节点
    visited[row][col] = true;//最开始的节点一定会被访问
    target.emplace_back(row,col);

    while(!Node.empty()){//循环遍历每一个需要走的节点
      vector curNode = Node[0];//.back();//获取最后一个元素

      int isKernel = 0;//是否是内部节点
      int i = 0, nextR = 0, nextC = 0;
      for(i = 0; i < 4; ++i){
        nextR = curNode[0]+dir[i];//获取要走的下一个元素的行
        nextC = curNode[1]+dir[i+1];//获取要走的下一个元素的列

        //如果节点可走,加入
        if(nextR >= 0 && nextR < grid.size() && nextC >= 0 && nextC < grid[0].size()){//合法
          if(!visited[nextR][nextC] && (curNode[2] == grid[nextR][nextC])){//当前位置没走过
            visited[nextR][nextC] = true;
            target.emplace_back(nextR,nextC);//存储要染色的目标
            vector tmp = {nextR,nextC,grid[nextR][nextC]};
            Node.emplace_back(tmp);
          }
        }

        if(nextR >= 0 && nextR < grid.size() && nextC >= 0 && nextC < grid[0].size() && grid[nextR][nextC] == curNode[2]){
          ++isKernel;

          if(isKernel == 4){//删除节点
            auto iter = find(target.begin(),target.end(),make_pair(curNode[0],curNode[1]));
            for(; iter != target.end();){
              target.erase(iter);
              iter =find(target.begin(),target.end(),make_pair(curNode[0],curNode[1]));
            }
          }
        }
      }
      Node.erase(Node.begin());//删除首元素
    }

    for(auto x: target){//全部染色
      grid[x.first][x.second] = color;
    }

    return grid;
  }
};

思路

本题的题目写得很屎,简单翻译一下

  • 和题目最开始选定的点,上下左右相邻任意一个,并且颜色相同,就是连通区域,大概率要染色(下一条解释为什么是大概率)
    • 如果点的周围都有连通区域,那么该点本身就不是边界,因此不能染色
      • eg:[1,1,1],[1,1,1],[1,1,1]。我们选取坐标为[1][1]的点,它的上下左右都是连通区域,因此[1][1]本身就不能被染色
  • 被染色的点作为新的点,判断新的点的连通区域,重复规则1

基于以上原则,我们的代码逻辑基本上就是以下几点:

  • 判断点curNode的周围是否存在颜色相同的点,如果有,以新点的基础上继续判断新点周围的点。
  • 如果curNode周围都有颜色相同的点,改点本身不能被染色。

解法

  • 循环遍历当前需要遍历的点,直到没有可以遍历的点为止
  • 从4个方向判别周围点是否可以被染色,如果可以,视为当前需要遍历的点,并对其存储
  • 如果点的4个方向都和中心点的颜色相同,那么中心点不能被染色。
  • 存储合法点的染色点。

2.dfs

class Solution {
    vector> target;
    int dir[5] = {-1,0,1,0,-1};//确定方向
public:
    vector> colorBorder(vector>& grid, int row, int col, int color) {
        int rowSize = grid.size(), colSize = grid[0].size();
        vector> visited(rowSize,vector(colSize));
        dfs(grid, visited, row, col, rowSize, colSize);
        for(auto x: target){
            grid[x.first][x.second] = color;
        }
        return grid;
    }

    void dfs(vector> grid, vector>& visited, int& row, int& col, int& rowSize, int& colSize){
        if(!(row>=0 && row=0 && col
            return ;
        }
        if(visited[row][col]){//访问过
            return ;
        }
        visited[row][col] = 1;//现在访问
        pair curNode = make_pair(row,col);
        int isKernal = 0;//是否是内部点

        for(int i = 0; i < 4; ++i){//确定下一个方位
            int nextR = curNode.first+dir[i];
            int nextC = curNode.second+dir[i+1];
            if(nextR>=0 && nextR=0 && nextC//合法位置并且color相同
                ++isKernal;
                dfs(grid,visited,nextR,nextC,rowSize, colSize);
            }
        }
        if(isKernal != 4){target.emplace_back(row,col);}
    }
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/969071.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号