leetcode 第205场周赛
第一题:替换所有的问号
链接:leetcode-cn.com/problems/re…
思路:
分三种情况讨论:(下标从0开始)
- i在首位,只需要判断第i+1位字符是不是c,如果是c的话则需要修改c的值,故c++
- i在中间位置,则需要判断i的前后位是否等于c,只要有一个相等,则需要修改c的值,故c++
- 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];
}
}