第 205 场力扣周赛题解

5507. 替换所有的问号

思路:直接找一个和相邻的字母不相同替换即可。

class Solution {
    public String modifyString(String s) {

        int n = s.length();
        StringBuilder ans = new StringBuilder();

        for (int i = 0; i < n; i++) {
            if (s.charAt(i) != '?')
                ans.append(s.charAt(i));
            else {
                char a = 'a';
                for (int j = 0; j < 26; j++) {
                    a = (char) (j + 'a');
                    if (i > 0 && ans.charAt(i - 1) == a ||
                            i < n - 1 && s.charAt(i + 1) == a)
                        continue;
                    break;
                }
                ans.append(a);
            }
        }

        return ans.toString();

    }
}

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

思路:map存一下平方数就好啦。

class Solution {
    public int numTriplets(int[] nums1, int[] nums2) {

        return work(nums1, nums2) + work(nums2, nums1);

    }

    private int work(int[] nums1, int[] nums2) {

        int ans = 0;
        int n = nums1.length;
        int m = nums2.length;
        Map<Long, Integer> map = new HashMap<>();


        for (int i = 0; i < n; i++)
            map.put((long) nums1[i] * nums1[i], map.getOrDefault((long) nums1[i] * nums1[i], 0) + 1);

        for (int i = 0; i < m; i++)
            for (int j = i + 1; j < m; j++)
                ans += map.getOrDefault((long) nums2[i] * nums2[j], 0);

        return ans;

    }
}

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

思路:用栈模拟即可。

class Solution {
    public int minCost(String s, int[] cost) {

        int ans = 0;
        int n = s.length();
        Stack<Integer> st = new Stack<>();

        for (int i = 0; i < n; i++) {
            if (!st.isEmpty() && s.charAt(st.peek()) == s.charAt(i)) {
                int index = st.pop();
                ans += Math.min(cost[index], cost[i]);
                if (cost[index] < cost[i]) index = i;
                st.add(index);
            } else
                st.add(i);
        }

        return ans;
    }
}

5510. 保证图可完全遍历

思路:我这边是拿最小生成树求解的,比较无脑,首先把类型3的边加上,然后通过并查集看是否还需要加类型1和类型2的边。

class Solution {

    private int ans;
    private int[] f1;
    private int[] f2;

    public int maxNumEdgesToRemove(int n, int[][] edges) {

        f1 = new int[n + 1];
        f2 = new int[n + 1];

        int m = edges.length;
        int size1 = 0, size2 = 0, size3 = 0;

        for (int i = 0; i <= n; i++)
            f1[i] = f2[i] = i;

        for (int i = 0; i < m; i++) {
            if (edges[i][0] == 1) size1++;
            else if (edges[i][0] == 2) size2++;
            else size3++;
        }

        int len1 = 0, len2 = 0, len3 = 0;
        int[][] edges1 = new int[size1][2];
        int[][] edges2 = new int[size2][2];
        int[][] edges3 = new int[size3][2];

        for (int i = 0; i < m; i++) {
            if (edges[i][0] == 1) {
                edges1[len1][0] = edges[i][1];
                edges1[len1++][1] = edges[i][2];
            } else if (edges[i][0] == 2) {
                edges2[len2][0] = edges[i][1];
                edges2[len2++][1] = edges[i][2];
            } else {
                edges3[len3][0] = edges[i][1];
                edges3[len3++][1] = edges[i][2];
            }
        }

        work(3, edges3);
        work(1, edges1);
        work(2, edges2);

        int last1 = f1[find1(1)], last2 = f2[find2(1)];

        //System.out.println(ans);

        for (int i = 1; i <= n; i++) {
            int t1 = f1[find1(i)];
            int t2 = f2[find2(i)];
            if (t1 != last1 || t2 != last2)
                return -1;
        }

        return m - ans;

    }

    private void work(int id, int[][] edges) {

        int n = edges.length;

        for (int i = 0; i < n; i++) {
            int t1 = find1(edges[i][0]);
            int t2 = find1(edges[i][1]);
            int t3 = find2(edges[i][0]);
            int t4 = find2(edges[i][1]);
            if (id == 1 && f1[t1] != t2) {
                ans++;
                f1[t1] = t2;
            }
            if (id == 2 && f2[t3] != t4) {
                ans++;
                f2[t3] = t4;
            }
            if (id == 3 && (f1[t1] != t2 || f2[t3] != t4)) {
                ans++;
                f1[t1] = t2;
                f2[t3] = t4;
            }
        }
    }

    private int find1(int x) {
        if (f1[x] == x)
            return x;
        return f1[x] = find1(f1[x]);
    }

    private int find2(int x) {
        if (f2[x] == x)
            return x;
        return f2[x] = find2(f2[x]);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值