LeetCode 第 206 场周赛 (统计、暴力、最小生成树、冒泡+贪心)

5511. 二进制矩阵中的特殊位置

class Solution {
     
public:
    int numSpecial(vector<vector<int>>& g) {
     
        int ans = 0, m = g.size(), n = g[0].size();
        for(int i=0;i<m;i++){
     
            for(int j=0;j<n;j++){
     
                int cnt = 0;
                for(int ii=0;ii<m;ii++)  cnt += g[ii][j];
                for(int jj=0;jj<n;jj++) cnt += g[i][jj];
                if(g[i][j] && cnt==2) ans++;
            }
        }
        return ans;
    }
};

5512. 统计不开心的朋友
无脑暴力,反正知道数据复杂度能过。

class Solution {
     
public:
    int unhappyFriends(int n, vector<vector<int>>& p, vector<vector<int>>& pairs) {
     
        int ans = 0;
        vector<bool> vis(n,false);
        for(int i=0;i<n/2;i++){
     
            for(int j=i+1;j<n/2;j++){
     
                if(check(pairs[i][0],pairs[j][0],pairs[i][1],p) &&  check(pairs[j][0],pairs[i][0],pairs[j][1],p)){
     
                    vis[pairs[i][0]] = 1;
                    vis[pairs[j][0]] = 1;
                }

                if(check(pairs[i][1],pairs[j][0],pairs[i][0],p) &&  check(pairs[j][0],pairs[i][1],pairs[j][1],p)){
     
                    vis[pairs[i][1]] = 1;
                    vis[pairs[j][0]] = 1;
                }                

                if(check(pairs[i][0],pairs[j][1],pairs[i][1],p) &&  check(pairs[j][1],pairs[i][0],pairs[j][0],p)){
     
                    vis[pairs[i][0]] = 1;
                    vis[pairs[j][1]] = 1;
                }                
                
                if(check(pairs[i][1],pairs[j][1],pairs[i][0],p) &&  check(pairs[j][1],pairs[i][1],pairs[j][0],p)){
     
                    vis[pairs[i][1]] = 1;
                    vis[pairs[j][1]] = 1;
                }
                
            }
        }
        for(int i=0;i<n;i++) ans += vis[i];
        return ans;
    }
    
    bool check(int a,int x,int y,const vector<vector<int>>& p){
     
        int f;
        for(int b:p[a]){
     
            if(b==x){
     
                f = b;
                break;
            }
            if(b==y){
     
                f = b;
                break;
            }
        }
        return f==x;
    }
};

5513. 连接所有点的最小费用

  • kruskal
struct UF{
     
    int fa[1000010];
    UF(){
     
        for(int i=0;i<=1000000;i++) fa[i] = i;
    }
    int find(int x){
     
        return x==fa[x]?x:fa[x] = find(fa[x]);
    }
    void merge(int x,int y){
     
        int fx = find(x);
        int fy = find(y);
        if(fx!=fy){
     
            fa[fx] = fy;
        }
    }
};

class Solution {
     
public:
    struct Edge{
     
        int u,v,w;
        Edge(int u,int v,int w):u(u),v(v),w(w){
     }
        bool operator<(const Edge& e) const{
     
            return w<e.w;
        }
    };
    vector<Edge> edges;
    int minCostConnectPoints(vector<vector<int>>& points) {
     
        UF uf;
        int n = points.size();
        for(int i=0;i<n;i++){
     
            for(int j=i+1;j<n;j++){
     
                edges.push_back(Edge(i+1,j+1,abs(points[i][0]-points[j][0])+abs(points[i][1]-points[j][1])));
            }
        }
        sort(edges.begin(),edges.end());
        int ans = 0;
        for(auto &e:edges){
     
            int x = uf.find(e.u);
            int y = uf.find(e.v);
            if(x!=y){
     
                uf.merge(x,y);
                ans += e.w;
            }
        }
        return ans;
    }
};
  • prim(此题是完全图、复杂度上更优)
class Solution {
     
public:
    int INF = 0x3f3f3f3f;
    int minCostConnectPoints(vector<vector<int>>& points) {
     
        int n = points.size(), ans = 0, dis[1010], vis[1010] = {
     0};
        memset(dis,INF,sizeof(dis));
        dis[0] = 0;
        for(int i=0;i<n;i++){
     
            int u = -1,min_cost = INF;
            for(int j=0;j<n;j++){
     
                if(!vis[j] && min_cost>dis[j]){
     
                    u = j;
                    min_cost = dis[j];
                }
            }
            vis[u] = 1;
            ans += min_cost;
            for(int j=0;j<n;j++){
     
                if(!vis[j]){
     
                    int new_cost = abs(points[u][0]-points[j][0])+abs(points[u][1]-points[j][1]);
                    dis[j] = min(dis[j],new_cost);
                }
            }
        }
        return ans;
    }
};

5514. 检查字符串是否可以通过排序子字符串得到另一个字符串
一个重要等价——虽然是可以任选一个子串去排序,但是却可以每次只选取两个相邻的字符去排序——就像冒泡一样。
但是这样的冒泡有一个前提—— ( x , y ) ( x < y ) (x,y)(x(x,y)(x<y)的时候不能交换。

比如现在想把8冒泡到最后,那么在8冒泡到最后面的时候,就不能有一个9出现,否则就无法交换。

class Solution {
     
public:
    bool isTransformable(string s, string t) {
     
        vector<int> pos[10];
        int n = s.size();
        for(int i=0;i<n;i++) pos[s[i]-'0'].push_back(i);
        for(int i=n-1;i>=0;i--){
     
            int c = t[i]-'0';
            if(pos[c].empty()) return false;
            int p = pos[c].back();
            pos[c].pop_back();
            for(int cc = c+1;cc<=9;cc++){
     
                if(pos[cc].size() && p<pos[cc].back()) return false;
            }
        }
        return true;
    }
};

你可能感兴趣的:(LeetCode,#,LC周赛)