【贪心】B000_LC_避免重复字母的最小删除成本 & 替换所有的问号(交换 | 双指针)
给你一个字符串 s 和一个整数数组 cost ,其中 cost[i] 是从 s 中删除字符 i 的代价。
返回使字符串任意相邻两个字母不相同的最小删除成本。
请注意,删除一个字符后,删除其他字符的成本不会改变。
输入:s = "abaac", cost = [1,2,3,4,5]
输出:3
解释:删除字母 "a" 的成本为 3,然后得到 "abac"(字符串中相邻两个字母不相同)
方法一:交换处理
这题我就在如何标记选了和没选那卡了15分钟,写了一大堆不优雅的代码才过;还是别人的思路比较简洁
如果 s[i]=s[i+1],且 cost[i]>cost[i+1],则选择删除s[i+1],并将 cost[i] 放到 i+1 位置为下一轮删除做准备
class Solution {
public:
int minCost(string& s, vector<int>& cs) {
int n=s.size(), ans=0;
for (int i=1; i<n; i++) {
if (s[i-1]==s[i]) {
ans+=min(cs[i-1], cs[i]);
if (cs[i-1]>cs[i]) swap(cs[i-1], cs[i]);
}
}
return ans;
}
};
复杂度分析
- Time:\(O(n)\),
- Space:\(O(1)\),
给你一个仅包含小写英文字母和 '?' 字符的字符串 s ,请你将所有的 '?' 转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。
注意:你 不能 修改非 '?' 字符。
题目测试用例保证 除 '?' 字符 之外,不存在连续重复的字符。
在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。
输入:s = "?zs"
输出:"azs"
解释:该示例共有 25 种解决方案,从 "azs" 到 "yzs" 都是符合题目要求的。只有 "z" 是无效的修改,因为字符串 "zzs" 中有连续重复的两个 'z'
class Solution {
public:
string modifyString(string& s) {
int n=s.size();
char now='a';
for (int i=0; i<n; i++) if (s[i]=='?') {
int l=i-1,r=i+1;
while (l>=0 && s[l]==now) {
now=(char) (now+1);
if (now>'z') now='a';
l--;
}
while (r<n && s[r]==now) {
now=(char) (now+1);
if (now>'z') now='a';
r++;
}
s[i]=now;
}
return s;
}
};