LeetCode 第 33 场双周赛(模拟、思维、数位统计+贪心、DFS || 并查集)

1556. 千位分隔数
模拟

class Solution {
    
    
public:
    string thousandSeparator(int n) {
    
    
        string s = to_string(n), ans; 
        int len = s.size(),cnt = 0;
        for(int i=len-1;i>=0;i--,cnt++){
    
    
            ans.push_back(s[i]);
            if((cnt+1)%3==0 && i!=0) ans.push_back('.');
        }
        reverse(ans.begin(),ans.end());
        return ans;
    }
};

1557. 可以到达所有点的最少点数目
思维题:
统计入度为0的点。

class Solution {
    
    
public:
    vector<int> findSmallestSetOfVertices(int n, vector<vector<int>>& edges) {
    
    
        vector<int> ans;
        int inDegree[100010] = {
    
    0};
        for(auto &v:edges){
    
    
            inDegree[v[1]]++;
        }
        for(int i=0;i<n;i++){
    
    
            if(inDegree[i]==0){
    
    
                ans.push_back(i);
            }
        }
        return ans;
    }
};

1558. 得到目标数组的最少函数调用次数
函数对某个数字加1,相当于对某个偶数的0位和1进行按位或运算。
函数对所有数字乘2,相当于把所有的数左移一位。
比如:
101
10
1000
最多只需左移3位,一共有4个1需要通过加1运算得到的。
所以最多需要调用7次。

class Solution {
    
    
public:
    int minOperations(vector<int>& nums) {
    
    
        int sum = 0,r = 0;
        for(int x:nums){
    
    
            auto pp = get(x);
            sum += pp.first;
            r = max(r,pp.second);
        }
        return sum+r;
    }
    pair<int,int> get(int n){
    
    
        int sum = 0, p = 0;
        while(n){
    
    
            p++;
            sum += (n&1);
            n = n>>1;
        }
        return make_pair(sum,p-1);
    }
};

1559. 二维网格图中探测环
首先环的长度大于等于4,无需考虑。
在dfs的时候,需要记录上一个搜索的点,以防“反复横跳”。
当搜到一个点两次的时候说明找到了环。
另外每次探测的时候,如果没有找到环,那么已经探测过的点就再也无需探测了。

const int dx[] ={
    
    -1,1,0,0,-1,-1,1,1};
const int dy[] = {
    
    0,0,-1,1,-1,1,-1,1};

class Solution {
    
    
public:
    bool vis[510][510] = {
    
    0};
    int m,n;
    bool containsCycle(vector<vector<char>>& g) {
    
    
        m = g.size();
        n = g[0].size();
        for(int i=0;i<m;i++){
    
    
            for(int j=0;j<n;j++){
    
    
                if(vis[i][j]==0){
    
    
                    if(ok(i,j,g,-1,-1)) return 1;
                }
            }
        }
        return 0;
    }
    bool ok(int x,int y,vector<vector<char>>& g,int px,int py){
    
    
        if(vis[x][y]) return true;
        vis[x][y] = 1;
        for(int k=0;k<4;k++){
    
    
            int nx = x+dx[k];
            int ny = y+dy[k];
            if(nx>=0 && nx<m && ny>=0  && ny<n && (nx!=px || ny!=py) && g[nx][ny]== g[x][y]){
    
    
                if(ok(nx,ny,g,x,y)) return true;
            }
        }
        return false;
    }
};
  • 并查集
    这个思想和最小生成树用并查集维护点的连通性以判断是否成环的方法非常类似。
    注意,每个点只需要访问一次,从上到下,从左到右,依次遍历,并且每次只向下方和右方拓展。
struct MF{
    
    
    int fa[250010];
    MF(){
    
    
        for(int i=0;i<=250000;i++) fa[i] = i;
    }
    int find(int x){
    
    
        return x==fa[x]?x:fa[x] = find(fa[x]);    
    }
    bool merge(int x,int y){
    
    
        int fx = find(x);
        int fy = find(y);
        if(fx==fy) return true;
        fa[fx] = fy;
        return false;
    }
};
class Solution {
    
    
public:
    int m,n;
    int id(int x,int y){
    
    
        return x*n+y;
    }
    bool containsCycle(vector<vector<char>>& g) {
    
    
        m = g.size();
        n = g[0].size();
        MF mf;
        for(int x=0;x<m;x++){
    
    
            for(int y=0;y<n;y++){
    
    
                int nx,ny;
                nx = x+1, ny = y;
                if(nx<m && ny<n && g[x][y]==g[nx][ny]){
    
    
                    if(mf.merge(id(x,y),id(nx,ny))){
    
    
                        return true;
                    }
                }
                nx = x, ny = y+1; 
                if(nx<m && ny<n && g[x][y] == g[nx][ny]){
    
    
                    if(mf.merge(id(x,y),id(nx,ny))){
    
    
                        return true;
                    }                    
                }                
            }
        }
        return false;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_44846324/article/details/108270258