题目:
给你一个字符串 s 和一个整数 k 。
定义函数 distance(s1, s2) ,用于衡量两个长度为 n 的字符串 s1 和 s2 之间的距离,即:
- 字符 
'a'到'z'按 循环 顺序排列,对于区间[0, n - 1]中的i,计算所有「s1[i]和s2[i]之间 最小距离」的 和 。 
例如,distance("ab", "cd") == 4 ,且 distance("a", "z") == 1 。
你可以对字符串 s 执行 任意次 操作。在每次操作中,可以将 s 中的一个字母 改变 为 任意 其他小写英文字母。
返回一个字符串,表示在执行一些操作后你可以得到的 字典序最小 的字符串 t ,且满足 distance(s, t) <= k 。
示例 1:
输入:s = "zbbz", k = 3
输出:"aaaz"
解释:在这个例子中,可以执行以下操作:
将 s[0] 改为 'a' ,s 变为 "abbz" 。
将 s[1] 改为 'a' ,s 变为 "aabz" 。
将 s[2] 改为 'a' ,s 变为 "aaaz" 。
"zbbz" 和 "aaaz" 之间的距离等于 k = 3 。
可以证明 "aaaz" 是在任意次操作后能够得到的字典序最小的字符串。
因此,答案是 "aaaz" 。
示例 2:
输入:s = "xaxcd", k = 4
输出:"aawcd"
解释:在这个例子中,可以执行以下操作:
将 s[0] 改为 'a' ,s 变为 "aaxcd" 。
将 s[2] 改为 'w' ,s 变为 "aawcd" 。
"xaxcd" 和 "aawcd" 之间的距离等于 k = 4 。
可以证明 "aawcd" 是在任意次操作后能够得到的字典序最小的字符串。
因此,答案是 "aawcd" 。
示例 3:
输入:s = "lol", k = 0
输出:"lol"
解释:在这个例子中,k = 0,更改任何字符都会使得距离大于 0 。
因此,答案是 "lol" 。
提示:
1 <= s.length <= 1000 <= k <= 2000s只包含小写英文字母。
思路:
首先要满足改变后的字符串 s' 与 s 的距离 <= k, 
那么其实可以从 s 出发进行BFS,找出所有满足条件的 s',然后找出字典序最小的那个
再进一步,按照字典序的计算规则,越左边的字母越小,那么字典序越小。
所以肯定优先动左侧的字符,让它变小, 这就进化成贪心
那么我们肯定希望 s' 左侧全是 a,这样是最小的。所以 k 可以理解为 允许从左侧字母变化的最大限制
代码:
class Solution {
public:
    string getSmallestString(string s, int k) {
        int idx = 0;  // 当前要处理的 s 的索引
        while (k && idx < s.size()) {
            int dis_to_a = min(s[idx] - 'a', 26 - (s[idx] - 'a'));
            if (k >= dis_to_a) {
                s[idx] = 'a';
                idx++;
                k -= dis_to_a;
            } else {
                // 通过 dis_to_a 让 s[idx] 尽量小
                // 此时 s[idx] 从左边走 和 从右边走 都到不了 a,为了变小就往左走
                s[idx] -= k;
                k = 0;
            }
        }
        return s;
    }
};