classSolution{public:
string modifyString(string s){
s ='#'+ s +'#';// 首尾添加哨兵int n = s.size(), t =0;// 判断原s中的字符是否为?for(int i =1; i < n -1; i ++){// 当前字符为?时进行替换if(s[i]=='?'){// 从a开始枚举char c ='a';// 若c与前后任一字符相同,枚举下一个while(c == s[i -1]|| c == s[i +1])
c++;// 替换
s[i]= c;}}// 返回时去除前后哨兵
s = s.substr(1, n -2);return s;}};
classSolution{public:intminCost(string s, vector<int>& cost){
s +='#';// 添加哨兵int sum =0, maxc = INT_MIN, res =0;for(int i =0; i < s.length()-1; i ++){// 计算当前重复字母删除成本之和,并记录单个字符最大删除成本
sum += cost[i], maxc =max(maxc, cost[i]);// 若当前字符与下一个字符不同,则执行删除程序if(s[i] != s[i +1]){// 总成本加上sum,若当前字母只有一个,则sum减去maxc后恰好为0
res += sum - maxc;// 重置sum与maxc
sum =0;
maxc = INT_MIN;}}return res;}};
classSolution{public:// 并查集intfind(vector<int>& st,int x){if(st[x]== x)return x;return st[x]=find(st, st[x]);}intmaxNumEdgesToRemove(int n, vector<vector<int>>& e){int m = e.size();int cnt =0;
vector<int> st1 = vector<int>(n +1);// 并查集初始化for(int i =1; i <= n; i ++) st1[i]= i;// 第一次克鲁斯卡尔算法,只针对第三种边,构建最小生成树for(int i =0; i < m; i ++){if(e[i][0]==3){int a = e[i][1], b = e[i][2];
a =find(st1, a), b =find(st1, b);if(a != b){
st1[a]= b;
cnt ++;}}}// st2拷贝于st1,分别用于构建alice和bob的最小生成树
vector<int>st2(st1);int cnt1 = cnt, cnt2 = cnt;for(int i =0; i < m; i ++){int a = e[i][1], b = e[i][2];if(e[i][0]==2){// bob的最小生成树,在第三种边的基础上添加bob专属边
a =find(st1, a), b =find(st1, b);if(a != b){
st1[a]= b;
cnt1 ++;}}elseif(e[i][0]==1){// alice的最小生成树,在第三种边的基础上添加alice专属边
a =find(st2, a), b =find(st2, b);if(a != b){
st2[a]= b;
cnt2 ++;}}}// 若alice或bob的最小生成树不存在,返回-1if(cnt1 != n -1|| cnt2 != n -1)return-1;// 总边数减去alice和bob的最小生成树边数(就是n-1),加上他们的公共边数(被减了两次)return m - cnt1 - cnt2 + cnt;}};