modify code

master
algorithmzuo 2 years ago
parent 1ceabcf714
commit 23816fe570

@ -0,0 +1,28 @@
package class_2022_08_4_week;
// 来自神策
// 给定一个数组arr表示连续n天的股价数组下标表示第几天
// 指标X任意两天的股价之和 - 此两天间隔的天数
// 比如
// 第3天价格是10
// 第9天价格是30
// 那么第3天和第9天的指标X = 10 + 30 - (9 - 3) = 34
// 返回arr中最大的指标X
// 时间复杂度O(N)
public class Code01_MaxXFromStock {
public static int maxX(int[] arr) {
if (arr == null || arr.length < 2) {
return -1;
}
// 0 + arr[0]
int preBest = arr[0];
int ans = 0;
for (int i = 1; i < arr.length; i++) {
ans = Math.max(ans, arr[i] - i + preBest);
preBest = Math.max(preBest, arr[i] + i);
}
return ans;
}
}

@ -0,0 +1,110 @@
package class_2022_08_4_week;
// 来自美团
// 8.20笔试
// 小团生日收到妈妈送的两个一模一样的数列作为礼物!
// 他很开心的把玩,不过不小心没拿稳将数列摔坏了!
// 现在他手上的两个数列分别为A和B长度分别为n和m。
// 小团很想再次让这两个数列变得一样。他现在能做两种操作:
// 操作一是将一个选定数列中的某一个数a改成数b这会花费|b-a|的时间,
// 操作二是选择一个数列中某个数a将它从数列中丢掉花费|a|的时间。
// 小团想知道,他最少能以多少时间将这两个数列变得再次相同!
// 输入描述:
// 第一行两个空格隔开的正整数n和m分别表示数列A和B的长度。
// 接下来一行n个整数分别为A1 A2…An
// 接下来一行m个整数分别为B1 B2…Bm
// 对于所有数据1 ≤ n,m ≤ 2000 |Ai|,|Bi| ≤ 10000
// 输出一行一个整数,表示最少花费时间,来使得两个数列相同。
public class Code02_ChangeToSame {
// A B
// zuo(A,B,0,0)
// A[ai.....] 对应 B[bi.....]
// 请变一样
// 返回最小代价
public static int zuo(int[] A, int[] B, int ai, int bi) {
if (ai == A.length && bi == B.length) {
return 0;
}
if (ai != A.length && bi == B.length) {
return A[ai] + zuo(A, B, ai + 1, bi);
}
if (ai == A.length && bi != B.length) {
return B[bi] + zuo(A, B, ai, bi + 1);
}
// A[ai] 有数 B[bi] 有数
// 可能性1 删掉A[ai]
int p1 = A[ai] + zuo(A, B, ai + 1, bi);
// 可能性2 删掉B[bi]
int p2 = B[bi] + zuo(A, B, ai, bi + 1);
// 可能性3 同时删掉
// int p3 = A[ai] + B[bi] + zuo(A, B, ai + 1, bi + 1);
// 可能性4 A[ai] -> B[bi] B[bi] -> A[ai]
int p4 = Math.abs(A[ai] - B[bi]) + zuo(A, B, ai + 1, bi + 1);
// 可能性5 A[ai] == B[bi]
return Math.min(p1, Math.min(p2, p4));
}
public static int minCost(int[] A, int[] B) {
int n = A.length;
int m = B.length;
int[][] dp = new int[n + 1][m + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
dp[i][j] = -1;
}
}
return change(A, B, 0, 0, dp);
}
// 暴力递归
// A[indexA....]和B[indexB....]完全一样
// 需要付出最少的代价返回
public static int change(int[] A, int[] B, int indexA, int indexB) {
if (indexA == A.length && indexB == B.length) {
return 0;
}
if (indexA == A.length && indexB != B.length) {
return B[indexB] + change(A, B, indexA, indexB + 1);
}
if (indexA != A.length && indexB == B.length) {
return A[indexA] + change(A, B, indexA + 1, indexB);
}
// indexA、indexB都没到最后
// 可能性1丢掉A[indexA]
int p1 = A[indexA] + change(A, B, indexA + 1, indexB);
// 可能性2丢掉B[indexB]
int p2 = B[indexB] + change(A, B, indexA, indexB + 1);
// 可能性3同时丢掉A[indexA]、B[indexB]
// 可能性4把A[indexA]改成B[indexB](也是B[indexB]改成A[indexA],因为代价一样)
// 可能性5A[indexA]本来就是等于B[indexB]的改的代价为0
// 可以分析出可能性3肯定是不如可能性4、可能性5的
// 所以舍弃掉可能性3
int p45 = Math.abs(A[indexA] - B[indexB]) + change(A, B, indexA + 1, indexB + 1);
return Math.min(Math.min(p1, p2), p45);
}
// 上面的暴力递归方法改动态规划
public static int change(int[] A, int[] B, int indexA, int indexB, int[][] dp) {
if (indexA == A.length && indexB == B.length) {
return 0;
}
if (dp[indexA][indexB] != -1) {
return dp[indexA][indexB];
}
int ans = 0;
if (indexA == A.length && indexB != B.length) {
ans = B[indexB] + change(A, B, indexA, indexB + 1);
} else if (indexA != A.length && indexB == B.length) {
ans = A[indexA] + change(A, B, indexA + 1, indexB);
} else {
int p1 = A[indexA] + change(A, B, indexA + 1, indexB);
int p2 = B[indexB] + change(A, B, indexA, indexB + 1);
int p45 = Math.abs(A[indexA] - B[indexB]) + change(A, B, indexA + 1, indexB + 1);
ans = Math.min(Math.min(p1, p2), p45);
}
dp[indexA][indexB] = ans;
return ans;
}
}

@ -0,0 +1,125 @@
package class_2022_08_4_week;
// 来自美团
// 8.20笔试
// 题目1
// 小美将要期中考试有n道题对于第i道题
// 小美有pi的几率做对获得ai的分值还有(1-pi)的概率做错得0分。
// 小美总分是每道题获得的分数。
// 小美不甘于此决定突击复习因为时间有限她最多复习m道题复习后的试题正确率为100%。
// 如果以最佳方式复习,能获得期望最大总分是多少?
// 输入n、m
// 接下来输入n个整数代表pi%为了简单期间将概率扩大了100倍。
// 接下来输入n个整数代表ai某道题的分值
// 输出最大期望分值精确到小数点后2位
// 数据 1m<=n<=50000
// 简单题, 课上提一下解法即可
// 题目2
// 小团在地图上放了3个定位装置想依赖他们进行定位
// 地图是一个n*n的棋盘
// 有3个定位装置(x1,y1),(x2,y2),(x3,y3),每个值均在[1,n]内。
// 小团在(a,b)位置放了一个信标,
// 每个定位装置会告诉小团它到信标的曼哈顿距离,也就是对于每个点,小团知道|xi-a|+|yi-b|
// 求信标位置,信标不唯一,输出字典序最小的。
// 输入n然后是3个定位装置坐标
// 最后是3个定位装置到信标的曼哈顿记录。
// 输出最小字典序的信标位置。
// 1 <= 所有数据值 <= 50000
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
public class Code03_FindPosition {
public static int[] find(int n,
int[] a, int[] b, int[] c,
int ad, int bd, int cd) {
int[] x1 = null;
int r1 = Integer.MAX_VALUE;
int[] x2 = null;
int r2 = 0;
int[] x3 = null;
int r3 = 0;
if (ad < r1) {
x1 = a;
r1 = ad;
x2 = b;
r2 = bd;
x3 = c;
r3 = cd;
}
if (bd < r1) {
x1 = b;
r1 = bd;
x2 = a;
r2 = ad;
x3 = c;
r3 = cd;
}
if (cd < r1) {
x1 = c;
r1 = cd;
x2 = a;
r2 = ad;
x3 = b;
r3 = bd;
}
// x1 r1 x2 r2 x3 r3
int[] cur = { x1[0] - r1, x1[1] };
Queue<int[]> queue = new LinkedList<>();
HashSet<String> visited = new HashSet<>();
ArrayList<int[]> ans = new ArrayList<>();
queue.add(cur);
visited.add(cur[0] + "_" + cur[1]);
while (!queue.isEmpty()) {
// cur x1为圆心r1为半径的圆周上
cur = queue.poll();
if (
cur[0] >= 1 && cur[0] <= n
&&
cur[1] >= 1 && cur[1] <= n
&&
distance(cur[0], cur[1], x2) == r2
&&
distance(cur[0], cur[1], x3) == r3) {
ans.add(cur);
}
if (ans.size() == 2) {
break;
}
add(cur[0] - 1, cur[1] - 1, x1, r1, queue, visited);
add(cur[0] - 1, cur[1], x1, r1, queue, visited);
add(cur[0] - 1, cur[1] + 1, x1, r1, queue, visited);
add(cur[0], cur[1] - 1, x1, r1, queue, visited);
add(cur[0], cur[1] + 1, x1, r1, queue, visited);
add(cur[0] + 1, cur[1] - 1, x1, r1, queue, visited);
add(cur[0] + 1, cur[1], x1, r1, queue, visited);
add(cur[0] + 1, cur[1] + 1, x1, r1, queue, visited);
}
if (ans.size() == 1
|| ans.get(0)[0] < ans.get(1)[0]
|| (ans.get(0)[0] == ans.get(1)[0] && ans.get(0)[1] < ans.get(1)[1])) {
return ans.get(0);
} else {
return ans.get(1);
}
}
public static void add(int x, int y,
int[] c, int r,
Queue<int[]> queue, HashSet<String> visited) {
String key = x + "_" + y;
if (distance(x, y, c) == r && !visited.contains(key)) {
queue.add(new int[] { x, y });
visited.add(key);
}
}
public static int distance(int x, int y, int[] c) {
return Math.abs(x - c[0]) + Math.abs(y - c[1]);
}
}

@ -0,0 +1,93 @@
package class_2022_08_4_week;
// 来自微软
// 给定一个字符串s只含有0~9这些字符
// 你可以使用来自s中的数字目的是拼出一个最大的回文数
// 使用数字的个数不能超过s里含有的个数
// 比如 :
// 39878能拼出的最大回文数是 : 898
// 00900能拼出的最大回文数是 : 9
// 54321能拼出的最大回文数是 : 5
// 最终的结果以字符串形式返回
// str的长度为N1 <= N <= 100000
// 测试链接 : https://leetcode.cn/problems/largest-palindromic-number/
import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;
public class Code04_MaxPalindromeNumber {
public static String largestPalindromic(String s) {
if (s == null || s.equals("")) {
return "";
}
HashMap<Integer, Integer> map = new HashMap<>();
int n = s.length();
for (int i = 0; i < n; i++) {
int number = s.charAt(i) - '0';
map.put(number, map.getOrDefault(number, 0) + 1);
}
PriorityQueue<Record> heap = new PriorityQueue<>(new RecordComparator());
for (int key : map.keySet()) {
heap.add(new Record(key, map.get(key)));
}
Record top = heap.poll();
if (top.times == 1) {
return String.valueOf(top.number);
} else if (top.number == 0) {
return String.valueOf(heap.isEmpty() ? 0 : heap.peek().number);
} else {
StringBuilder left = new StringBuilder();
left.append(top.number);
top.times -= 2;
if (top.times > 0) {
heap.add(top);
}
while (!heap.isEmpty() && heap.peek().times > 1) {
top = heap.poll();
left.append(top.number);
top.times -= 2;
if (top.times > 0) {
heap.add(top);
}
}
StringBuilder ans = new StringBuilder();
for (int i = 0; i < left.length(); i++) {
ans.append(left.charAt(i));
}
if (!heap.isEmpty()) {
ans.append(heap.peek().number);
}
for (int i = left.length() - 1; i >= 0; i--) {
ans.append(left.charAt(i));
}
return ans.toString();
}
}
public static class Record {
public int number;
public int times;
public Record(int n, int t) {
number = n;
times = t;
}
}
public static class RecordComparator implements Comparator<Record> {
@Override
public int compare(Record o1, Record o2) {
if (o1.times == 1 && o2.times > 1) {
return 1;
}
if (o1.times > 1 && o2.times == 1) {
return -1;
}
return o2.number - o1.number;
}
}
}

@ -0,0 +1,85 @@
package class_2022_08_4_week;
// 来自微软
// 给定两个数组A和B比如
// A = { 0, 1, 1 }
// B = { 1, 2, 3 }
// A[0] = 0, B[0] = 1表示0到1有双向道路
// A[1] = 1, B[1] = 2表示1到2有双向道路
// A[2] = 1, B[2] = 3表示1到3有双向道路
// 给定数字N编号从0~N所以一共N+1个节点
// 题目输入一定保证所有节点都联通,并且一定没有环
// 默认办公室是0节点其他1~N节点上每个节点上都有一个居民
// 每天所有居民都去往0节点上班
// 所有的居民都有一辆5座的车也都乐意和别人一起坐车
// 车不管负重是多少只要走过一条路就耗费1的汽油
// 比如A、B、C的居民开着自己的车来到D居民的位置一共耗费3的汽油
// D居民和E居民之间假设有一条路
// 那么D居民可以接上A、B、C4个人可以用一辆车去往E的话就再耗费1的汽油
// 求所有居民去办公室的路上,最少耗费多少汽油
import java.util.ArrayList;
public class Code05_TravelMinFuel {
public static int cnt = 0;
public static int minFuel(int[] a, int[] b, int n) {
// 先建图
ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<>());
}
for (int i = 0; i < a.length; i++) {
graph.get(a[i]).add(b[i]);
graph.get(b[i]).add(a[i]);
}
// 建图完毕
// 根据题目描述办公室一定是0号点
// 所有员工一定是往0号点汇聚
// a 号dfn[a] == 0 没遍历过!
// dfn[a] != 0 遍历过!
int[] dfn = new int[n + 1];
// a为头的树一共有10个节点
// size[a] = 0
// size[a] = 10
int[] size = new int[n + 1];
// 所有居民要汇总吗?
// a为头的树所有的居民是要向a来汇聚
// cost[a] : 所有的居民要向a来汇聚总油量的耗费
int[] cost = new int[n + 1];
cnt = 0;
dfs(graph, 0, dfn, size, cost);
return cost[0];
}
// 图 graph
// 当前的头原来的编号不是dfn序号 : cur
// 从cur开始请遍历
// 遍历完成后请把dfn[cur]填好size[cur]填好cost[cur]填好
public static void dfs(ArrayList<ArrayList<Integer>> graph, int cur, int[] dfn, int[] size, int[] cost) {
dfn[cur] = ++cnt;
size[cur] = 1;
for (int next : graph.get(cur)) {
if (dfn[next] == 0) {
dfs(graph, next, dfn, size, cost);
size[cur] += size[next];
cost[cur] += cost[next];
cost[cur] += (size[next] + 4) / 5;
}
}
}
public static void main(String[] args) {
int[] a1 = { 0, 1, 1 };
int[] b1 = { 1, 2, 3 };
int n1 = 3;
System.out.println(minFuel(a1, b1, n1));
int[] a2 = { 1, 1, 1, 9, 9, 9, 9, 7, 8 };
int[] b2 = { 2, 0, 3, 1, 6, 5, 4, 0, 0 };
int n2 = 9;
System.out.println(minFuel(a2, b2, n2));
}
}

@ -0,0 +1,192 @@
package class_2022_08_4_week;
// 来自网易
// 小红拿到了一个仅由r、e、d组成的字符串
// 她定义一个字符e为"好e" : 当且仅当这个e字符和r、d相邻
// 例如"reeder"只有一个"好e"前两个e都不是"好e"只有第三个e是"好e"
// 小红每次可以将任意字符修改为任意字符,即三种字符可以相互修改
// 她希望"好e"的数量尽可能多
// 小红想知道,自己最少要修改多少次
// 输入一个只有r、e、d三种字符的字符串
// 长度 <= 2 * 10^5
// 输出最小修改次数
public class Code06_MinCostMostE {
// public static class Info {
// public int mostGoodE;
// public int minCost;
//
// public Info(int good, int cost) {
// mostGoodE = good;
// minCost = cost;
// }
//
// }
//
// // i-2 -> prepre
// // i-1 -> pre
// // i...可以去成全 i-1 pre
// // 也可以不成全
// // i -> r e d 随意
// // 返回i-1 yes or no + i.... 最多的好e数量是多少
// // 最多的好e, 最小的代价
// // i 2 * 10^5
// // prepre r e d
// // pre r e d
// // 9 * 2 * 10^5
// // 10^6
// public static Info zuo(char[] s, int i, char prepre, char pre) {
// if (i == s.length) {
// return new Info(0, 0);
// }
//
// // 可能性1 i-1 [i] -> r
// int cur1Value = prepre == 'd' && pre == 'e' ? 1 : 0;
// int cur1Cost = s[i] == 'r' ? 0 : 1;
// Info info1 = zuo(s, i + 1, pre, 'r');
// int p1Value = cur1Value + info1.mostGoodE;
// int p1Cost = cur1Cost + info1.minCost;
//
// // 可能性2 i-1 [i] -> e
// int cur2Value = 0;
// int cur2Cost = s[i] == 'e' ? 0 : 1;
// Info info2 = zuo(s, i + 1, pre, 'e');
// int p2Value = cur2Value + info2.mostGoodE;
// int p2Cost = cur2Cost + info2.minCost;
//
// // 可能性3 i-1 [i] -> d
// int cur3Value = prepre == 'r' && pre == 'e' ? 1 : 0;
// int cur3Cost = s[i] == 'd' ? 0 : 1;
// Info info3 = zuo(s, i + 1, pre, 'd');
// int p3Value = cur3Value + info3.mostGoodE;
// int p3Cost = cur3Cost + info3.minCost;
//
// int mostE = 0;
// int minCost = Integer.MAX_VALUE;
//
// if (mostE < p1Value) {
// mostE = p1Value;
// minCost = p1Cost;
// } else if (mostE == p1Value) {
// minCost = Math.min(minCost, p1Cost);
// }
//
// if (mostE < p2Value) {
// mostE = p2Value;
// minCost = p2Cost;
// } else if (mostE == p2Value) {
// minCost = Math.min(minCost, p2Cost);
// }
//
// if (mostE < p3Value) {
// mostE = p3Value;
// minCost = p3Cost;
// } else if (mostE == p3Value) {
// minCost = Math.min(minCost, p3Cost);
// }
// return new Info(mostE, minCost);
// }
public static int minCost(String str) {
int n = str.length();
if (n < 3) {
return -1;
}
int[] arr = new int[n];
// d认为是0e认为是1r认为是2
for (int i = 0; i < n; i++) {
char cur = str.charAt(i);
if (cur == 'd') {
arr[i] = 0;
} else if (cur == 'e') {
arr[i] = 1;
} else {
arr[i] = 2;
}
}
// 通过上面的转化,问题变成了:
// 1的左右一定要被0和2包围这个1才是"好1"
// 请让"好1"的尽量多,返回最少的修改代价
int maxGood = 0;
int minCost = Integer.MAX_VALUE;
for (int prepre = 0; prepre < 3; prepre++) {
for (int pre = 0; pre < 3; pre++) {
int cost = arr[0] == prepre ? 0 : 1;
cost += arr[1] == pre ? 0 : 1;
Info cur = process(arr, 2, prepre, pre);
if (cur.maxGood > maxGood) {
maxGood = cur.maxGood;
minCost = cur.minCost + cost;
} else if (cur.maxGood == maxGood) {
minCost = Math.min(minCost, cur.minCost + cost);
}
}
}
return minCost;
}
public static class Info {
public int maxGood;
public int minCost;
public Info(int a, int b) {
maxGood = a;
minCost = b;
}
}
// 暴力递归
// 可以自己改成动态规划
// arr[index-2]位置的数值是prepre
// arr[index-1]位置的数值是pre
// 在这种情况下请让arr[index...]上的好1尽量多
// 返回:
// 尽量多的"好1",是多少?
// 得到尽量多的"好1",最小代价是多少?
public static Info process(int[] arr, int index, int prepre, int pre) {
if (index == arr.length) {
return new Info(0, 0);
}
// 可能性1arr[index]变成0
int p1Value = prepre == 2 && pre == 1 ? 1 : 0;
int p1Cost = arr[index] == 0 ? 0 : 1;
Info info = process(arr, index + 1, pre, 0);
p1Value += info.maxGood;
p1Cost += info.minCost;
// 可能性2arr[index]变成1
int p2Value = 0;
int p2Cost = arr[index] == 1 ? 0 : 1;
info = process(arr, index + 1, pre, 1);
p2Value += info.maxGood;
p2Cost += info.minCost;
// 可能性3arr[index]变成2
int p3Value = prepre == 0 && pre == 1 ? 1 : 0;
int p3Cost = arr[index] == 2 ? 0 : 1;
info = process(arr, index + 1, pre, 2);
p3Value += info.maxGood;
p3Cost += info.minCost;
// 开始决策,选出三种可能性中的最优解
int maxGood = 0;
int minCost = Integer.MAX_VALUE;
if (p1Value > maxGood) {
maxGood = p1Value;
minCost = p1Cost;
} else if (p1Value == maxGood) {
minCost = Math.min(minCost, p1Cost);
}
if (p2Value > maxGood) {
maxGood = p2Value;
minCost = p2Cost;
} else if (p2Value == maxGood) {
minCost = Math.min(minCost, p2Cost);
}
if (p3Value > maxGood) {
maxGood = p3Value;
minCost = p3Cost;
} else if (p3Value == maxGood) {
minCost = Math.min(minCost, p3Cost);
}
return new Info(maxGood, minCost);
}
}

@ -1633,4 +1633,98 @@ https://leetcode.cn/problems/smallest-rotation-with-highest-score/
第037节 2022年8月第4周流行算法题目解析
来自神策
给定一个数组arr表示连续n天的股价数组下标表示第几天
指标X任意两天的股价之和 - 此两天间隔的天数
比如
第3天价格是10
第9天价格是30
那么第3天和第9天的指标X = 10 + 30 - (9 - 3) = 34
返回arr中最大的指标X
来自美团
8.20笔试
小团生日收到妈妈送的两个一模一样的数列作为礼物!
他很开心的把玩,不过不小心没拿稳将数列摔坏了!
现在他手上的两个数列分别为A和B长度分别为n和m。
小团很想再次让这两个数列变得一样。他现在能做两种操作:
操作一是将一个选定数列中的某一个数a改成数b这会花费|b-a|的时间,
操作二是选择一个数列中某个数a将它从数列中丢掉花费|a|的时间。
小团想知道,他最少能以多少时间将这两个数列变得再次相同!
输入描述:
第一行两个空格隔开的正整数n和m分别表示数列A和B的长度。
接下来一行n个整数分别为A1 A2…An
接下来一行m个整数分别为B1 B2…Bm
对于所有数据1 ≤ n,m ≤ 2000 |Ai|,|Bi| ≤ 10000
输出一行一个整数,表示最少花费时间,来使得两个数列相同。
来自美团
题目1
8.20笔试
小美将要期中考试有n道题对于第i道题
小美有pi的几率做对获得ai的分值还有(1-pi)的概率做错得0分。
小美总分是每道题获得的分数。
小美不甘于此决定突击复习因为时间有限她最多复习m道题复习后的试题正确率为100%。
如果以最佳方式复习,能获得期望最大总分是多少?
输入n、m
接下来输入n个整数代表pi%为了简单期间将概率扩大了100倍。
接下来输入n个整数代表ai某道题的分值
输出最大期望分值精确到小数点后2位
数据 1m<=n<=50000
简单题, 课上提一下解法即可
题目2
小团在地图上放了3个定位装置想依赖他们进行定位
地图是一个n*n的棋盘
有3个定位装置(x1,y1),(x2,y2),(x3,y3),每个值均在[1,n]内。
小团在(a,b)位置放了一个信标,
每个定位装置会告诉小团它到信标的曼哈顿距离,也就是对于每个点,小团知道|xi-a|+|yi-b|
求信标位置,信标不唯一,输出字典序最小的。
输入n然后是3个定位装置坐标
最后是3个定位装置到信标的曼哈顿记录。
输出最小字典序的信标位置。
1 <= 所有数据值 <= 50000
来自微软
给定一个字符串s只含有0~9这些字符
你可以使用来自s中的数字目的是拼出一个最大的回文数
使用数字的个数不能超过s里含有的个数
比如 :
39878能拼出的最大回文数是 : 898
00900能拼出的最大回文数是 : 9
54321能拼出的最大回文数是 : 5
最终的结果以字符串形式返回
str的长度为N1 <= N <= 100000
测试链接 : https://leetcode.cn/problems/largest-palindromic-number/
来自微软
给定两个数组A和B比如
A = { 0, 1, 1 }
B = { 1, 2, 3 }
A[0] = 0, B[0] = 1表示0到1有双向道路
A[1] = 1, B[1] = 2表示1到2有双向道路
A[2] = 1, B[2] = 3表示1到3有双向道路
给定数字N编号从0~N所以一共N+1个节点
题目输入一定保证所有节点都联通,并且一定没有环
默认办公室是0节点其他1~N节点上每个节点上都有一个居民
每天所有居民都去往0节点上班
所有的居民都有一辆5座的车也都乐意和别人一起坐车
车不管负重是多少只要走过一条路就耗费1的汽油
比如A、B、C的居民开着自己的车来到D居民的位置一共耗费3的汽油
D居民和E居民之间假设有一条路
那么D居民可以接上A、B、C4个人可以用一辆车去往E的话就再耗费1的汽油
求所有居民去办公室的路上,最少耗费多少汽油
来自网易
小红拿到了一个仅由r、e、d组成的字符串
她定义一个字符e为"好e" : 当且仅当这个e字符和r、d相邻
例如"reeder"只有一个"好e"前两个e都不是"好e"只有第三个e是"好e"
小红每次可以将任意字符修改为任意字符,即三种字符可以相互修改
她希望"好e"的数量尽可能多
小红想知道,自己最少要修改多少次
输入一个只有r、e、d三种字符的字符串
长度 <= 2 * 10^5
输出最小修改次数

Loading…
Cancel
Save