LeetCode第228场题解

第一次ak,值得开心一下下。(虽然这场很简单)嘻嘻嘻~
1、生成交替二进制字符串的最少操作数

Solution

有两钟不同的交替字符串,010101 和 101010
比较生成两种交替字符串的操作数,选择少的

AC Code
class Solution {
    
    
public:
    int minOperations(string s) {
    
    
        int a=0,b=0;
        int len = s.length();
        for(int i=0;i<len;i++){
    
    
            if((s[i]=='0'&&i%2) || (s[i]=='1'&&i%2==0)) a++;//010101
            if((s[i]=='0'&&i%2==0) || (s[i]=='1'&&i%2)) b++;//101010
        }
        return min(a,b);
    }
};

2、统计同构子字符串的数目

Solution

可以从示例中得到答案:组合数之和
将字符串按连续相同分割
如:abbcccaa — a,bb,ccc,aa
答案:(1x2)/2+(2x3)/2+(3x4)/2+(2x3)/2=13

AC Code
class Solution {
    
    
public:
    int countHomogenous(string s) {
    
    
        long long ans=0;
        int mod = 1e9+7;
        int len = s.length();
        int pre=0;
        int num=0;
        for(int i=1;i<len;i++){
    
    
            if(s[i]!=s[i-1]){
    
    
                num = i-pre;
                ans+=(1ll*(num)*(num+1)/2)%mod;
                pre=i;
            }
        }
        num=len-pre;
        ans+=(1ll*(num)*(num+1)/2)%mod;
        return ans;
    }
};

3、袋子里最少数目的球

Solution

二分,一般来说求“最大值最小化”都可以尝试二分
直接二分单个袋子里球数目的最大值

AC Code
class Solution {
    
    
public:
    bool check(int x,vector<int>& nums,int m){
    
    
        for(int i : nums){
    
    
            m-=(i/x);
            if(i%x==0) m+=1;//如9可两次分为3,3,3
        }
        return m<0;
    }
    int minimumSize(vector<int>& nums, int maxOperations) {
    
    
        long long L=1,R=0,mid;
        for(int i:nums){
    
    
            if(i>R) R=i;
        }
        while(L<=R){
    
    
            mid=(L+R)>>1;
            if(check(mid,nums,maxOperations)) L=mid+1;
            else R=mid-1;
        }
        return L;
    }
};

4、一个图中连通三元组的最小度数

Solution

注意到数据范围很小,可以尝试暴力,可ac

AC Code
class Solution {
    
    
public:
    int minTrioDegree(int n, vector<vector<int>>& edges) {
    
    
        long long ans=0x3f3f3f3f;
        bool t[410][410]={
    
    0};//图
        int d[410]={
    
    0};//顶点的度
        int len = edges.size();
        for(int i=0;i<len;i++){
    
    
            t[edges[i][0]][edges[i][1]]=1;
            t[edges[i][1]][edges[i][0]]=1;
            d[edges[i][0]]++;
            d[edges[i][1]]++;
        }
        bool v=0;
        for(int i=1;i<=n;i++){
    
    
            for(int j=i+1;j<=n;j++){
    
    
                for(int k=j+1;k<=n;k++){
    
    
                    if(t[i][j] && t[j][k] && t[k][i]){
    
    //找到一个连通三元组
                        v=1;
                        long long temp = d[i]+d[j]+d[k]-6;//连通三元组中每个顶点都于其余两个顶点有边
                        if(ans>temp) ans = temp;
                    }
                }
            }
        }
        if(v) return ans;
        else return -1;
    }
};

希望对你有帮助!

猜你喜欢

转载自blog.csdn.net/buibuilili/article/details/113806946