leetcode 第205场周赛

99 阅读1分钟

leetcode 第205场周赛

第一题:替换所有的问号

链接:leetcode-cn.com/problems/re…

思路:

分三种情况讨论:(下标从0开始)

  1. i在首位,只需要判断第i+1位字符是不是c,如果是c的话则需要修改c的值,故c++
  2. i在中间位置,则需要判断i的前后位是否等于c,只要有一个相等,则需要修改c的值,故c++
  3. i在最后一位,则只需要判断第i-1是否为c, 如果是c的话则需要修改c的值,故c++

代码

public class Solution {
    public String modifyString(String s) {
        char[] sChar = s.toCharArray();
        int len = sChar.length;
        for (int i = 0; i < len; i++) {
            if (sChar[i] != '?') continue;
            // 此时sChar[i] 一定是'?'
            // 默认替换的值是‘a’
            char c = 'a';
            //得到可以替换'?'的字符
            while (i != 0 && sChar[i - 1] == c || i + 1 < len && sChar[i + 1] == c) {
                c++;
            }
            sChar[i] = c;
        }
        return String.valueOf(sChar);
    }
}

第二题:数的平方等于两数乘积的方法数

链接:leetcode-cn.com/problems/nu…

思路:

将nums1中元素的平方存储在hash表中,key=元素的平方,value=元素的平方出现的次数,双重循环得到nums2的值,到hash表中查找

代码:

public class Solution {
    public static int numTriplets(int[] nums1, int[] nums2) {
        return work(nums1, nums2) + work(nums2, nums1);
    }

    public static int work(int[] nums1, int[] nums2) {
        int res = 0;
        Map<Long, Integer> map = new HashMap<>();
        for (int num1 : nums1) {
            Long tmp = (long) num1 * num1;
            if (map.containsKey(tmp)) {
                map.put(tmp, map.get(tmp) + 1);
            } else {
                map.put(tmp, 1);
            }
        }

        for (int i = 0; i < nums2.length - 1; i++) {
            for (int j = i + 1; j < nums2.length; j++) {
                Long multi =  (long) nums2[i] * nums2[j];
                if (map.containsKey(multi)) {
                    res += map.get(multi);
                }
            }
        }

        return res;
    }
}

第三题:避免重复字母的最小删除成本

链接:leetcode-cn.com/problems/mi…

思路:

动态规划(还没弄明白。。。)

代码(有问题)

public class Solution {
    public static int minCost(String s, int[] cost) {
        int len = s.length();
        char[] chars = s.toCharArray();
        // j 表示前i个字母删除完了之后,最后剩下的字母是什么
        int[][] f = new int[len][27];
        int INF = 10000000;

        for (int i = 0; i < f.length; i++) {
            for (int j = 0; j < 27; j++) {
                f[i][j] = INF;
            }
        }
        f[0][chars[0] - 'a'] = 0;
        f[0][26] = cost[0];

        for (int i = 1; i < len; i++) {
            for (int j = 0; j < 27; j++) {
                f[i][j] = f[i - 1][j] + cost[i];
            }
            int j = chars[i] - 'a';
            for (int k = 0; k < 27; k++) {
                if (k != j) {
                    f[i][j] = Math.min(f[i][j], f[i - 1][k]);
                }
            }
        }
        int res = INF;
        for (int i = 0; i < 27; i++) {
            res = Math.min(res, f[len - 1][i]);
        }

        return res;
    }
}

第四题:保证图可完全遍历

链接:leetcode-cn.com/problems/re…

思路:

该题目等价于:最少留多少边可以保证图可完全遍历。

利用最小生成树去做

代码

public class Solution {
    public static int[] pa;
    public static int[] pb;
    public int maxNumEdgesToRemove(int n, int[][] edges) {
        pa = new int[n + 1];
        pb = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            pa[i] = i;
            pb[i] = i;
        }

        int res = 0, ca = n, cb = n;
        for (int[] edge : edges) {
            if (edge[0] == 3) {
                int x = edge[1], y = edge[2];
                int pax = find(pa, x);
                int pay = find(pa, y);
                int pbx = find(pb, x);
                int pby = find(pb, y);
                if (pax != pby) {
                    pa[pax] = pay;
                    ca--;
                    pb[pbx] = pby;
                    cb--;
                } else {
                    res++;
                }
            }
        }

        for (int[] edge : edges) {
            int t = edge[0], x = edge[1], y = edge[2];
            if (t == 3) continue;
            if (t == 1) {
                int pax = find(pa, x), pay = find(pa, y);
                if (pax != pay) {
                    pa[pax] = pay;
                    ca--;
                } else {
                    res++;
                }
            } else {
                int pbx = find(pb, x), pby = find(pb, y);
                if (pbx != pby) {
                    pb[pbx] = pby;
                    cb--;
                } else {
                    res++;
                }
            }
        }

        if (ca > 1 || cb > 1) return -1;
        return res;
    }

    public static int find(int[] p, int x) {
        if (p[x] != x) {
            p[x] = find(p, p[x]);
        }
        return p[x];
    }
}