LeetCode第205场周赛

leetcode 205周赛

替换所有的问号

枚举每个字符判断是不是'?'如果是则进行更改

目的是使最终的字符串不包含任何 连续重复 的字符,不连续使用一个字符即符合要求,则abababab.....便可符合

故整体思想是,连续'?'中第奇数个改为 a,偶数改为b

class Solution {
public:
    string modifyString(string s) {
        for (int i = 0; i < s.size(); i ++){
            while(s[i] == '?' && i < s.size()){
                if ((i + 1) % 2) s[i] = 'a';//因为是从0遍历,故用i + 1 用来判断奇偶
                else s[i] = 'b';
                if(i != 0 && s[i - 1] == s[i]) s[i] = 'c';//经过更改为 a 或 b 之后,防止和其前一字符相同,故改为c
                i ++;
            }
            if (i != 0 && s[i - 1] == s[i]) s[i - 1] += 2;//经过更改为 a 或 b 之后,防止和其后一字符相同,故改为d
        }
        return s;
    }
};

数的平方等于两数乘积的方法数

暴力枚举

先用map吧所有数存起来,得到每个数出现的次数;

b = a * a / c, 然后去查找b的个数,如果b == c,就说明b和c的位置一样,要减一

然后最终答案 / 2(因为0 <= j < k <)

class Solution {
public:
    typedef long long ll;
    map<ll, ll> mp1, mp2;
    int numTriplets(vector<int>& nums1, vector<int>& nums2) {
        int ans = 0;
        int len1 = nums1.size(), len2 = nums2.size();
        for (int i = 0; i < len1; i ++) mp1[nums1[i]] ++;
        for (int i = 0; i < len2; i ++) mp2[nums2[i]] ++;
        for (int i = 0; i < len1; i ++)
            for (int j = 0; j < len2; j ++){
                ll b = (ll)nums1[i] * nums1[i] / nums2[j];
                if (b * nums2[j] != (ll)nums1[i] * nums1[i])
                    continue;
                else {
                    ans += mp2[b];
                    if (b == nums2[j]) ans --;
                }
            }
        for (int i = 0; i < len2; i ++)
            for (int j = 0; j < len1; j ++){
                ll b = (ll)nums2[i] * nums2[i] / nums1[j];
                if (b * nums1[j] != (ll)nums2[i] * nums2[i])
                    continue;
                else {
                    ans += mp1[b];
                    if (b == nums1[j]) ans --;
                }
            }
        return ans / 2;
    }
};

避免重复字母的最小删除成本

贪心简单题

逐个遍历,要删除全部连续的字母所消耗代价最小,即保留代价最大的字符。

初始化 最大值为cost[0],求出所有相同字符总代价减去最大值即可

class Solution {
public:
    const int MAX = 0x3fffffff;
    int minCost(string s, vector<int>& cost) {
        int maxx = cost[0], sum = cost[0], ans = 0;
        bool flag = 0;
        for (int i = 1; i < s.size(); i ++){
            if(s[i] == s[i - 1]){
                sum += cost[i];
                maxx = max(maxx, cost[i]);
                flag = 1;
            }
            else if(flag){
                ans += sum - maxx;
                maxx = cost[i];
                sum = cost[i];
                flag = 0;
            }
            else{
                maxx = cost[i];
                sum = cost[i];
            }
        }
        if (flag){
            ans += sum - maxx;
        }
        return ans;
    }
};

保证图可完全遍历

并查集
先把两个人都可以走的放进并查集,拷贝一个副本
然后在对第一个人的边放进并查集1里面
然后再对第二个人的边放进并查集2里面

如果可以形成MST,就是联通的,否则就不联通

class Solution {
public:
	int fa[100010],fa2[100010];
	int find(int x){
		return x == fa[x]? x : fa[x] = find(fa[x]);
	}
	int find2(int x){
		return x == fa2[x]? x : fa2[x] = find2(fa2[x]);
	}
    int maxNumEdgesToRemove(int N, vector<vector<int>>& edges) {
    	int ans = 0,cnt1 = 0,cnt2 = 0;
        for(int i =1;i<=N;i++) fa[i] = i;
        for(auto line:edges){
        	int t = line[0],x = line[1],y = line[2];
        	if(t == 3){
        		int fx = find(x),fy = find(y);
        		if(fx == fy) ans++;
        		else {
        			fa[fx] = fy;
        			cnt1++,cnt2++;
        		}
        	}
        }
        for(int i = 1;i<=N;i++) fa2[i] = fa[i];
        for(auto line:edges){
        	int t = line[0],x = line[1],y = line[2];
        	if(t == 1){
        		int fx = find(x),fy = find(y);
        		if(fx == fy) ans++;
        		else {
        			fa[fx] = fy;
        			cnt1++;
        		}
        	}
        }
        for(auto line:edges){
        	int t = line[0],x = line[1],y = line[2];
        	if(t == 2){
        		int fx = find2(x),fy = find2(y);
        		if(fx == fy) ans++;
        		else {
        			fa2[fx] = fy;
        			cnt2++;
        		}
        	}
        }
        if(cnt1 != N-1 || cnt2 != N-1) return -1;
        else return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值