1. 程式人生 > 實用技巧 >【貪心】B000_LC_避免重複字母的最小刪除成本 & 替換所有的問號(交換 | 雙指標)

【貪心】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;
    }
};