LeetCode第228场题解

本文介绍了四个算法问题的解决方案:1) 最少操作数生成交替二进制字符串;2) 统计同构子字符串数量;3) 求解最少球数填满袋子;4) 图中连通三元组的最小度数。通过ACCode展示了解题思路,涉及字符串处理、组合数学和二分查找等技巧。
摘要由CSDN通过智能技术生成

第一次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;
    }
};

希望对你有帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值