【贪心】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;
    }
};
posted @ 2020-09-06 17:46  童年の波鞋  阅读(174)  评论(0编辑  收藏  举报