跳转至

3106. 满足距离约束且字典序最小的字符串

题目描述

给你一个字符串 s 和一个整数 k

定义函数 distance(s1, s2) ,用于衡量两个长度为 n 的字符串 s1s2 之间的距离,即:

  • 字符 '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 <= 100
  • 0 <= k <= 2000
  • s 只包含小写英文字母。

解法

方法一:枚举

我们可以遍历字符串 $s$ 的每个位置,对于每个位置,我们枚举所有小于当前字符的字符,计算改变到这个字符的代价 $d$,如果 $d \leq k$,我们就将当前位置的字符改为这个字符,并将 $k$ 减去 $d$,然后结束枚举,继续遍历下一个位置。

遍历结束后,我们就得到了一个满足条件的字符串。

时间复杂度 $O(n \times |\Sigma|)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度;而 $|\Sigma|$ 是字符集的大小,本题中 $|\Sigma| \leq 26$。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution:
    def getSmallestString(self, s: str, k: int) -> str:
        cs = list(s)
        for i, c1 in enumerate(s):
            for c2 in ascii_lowercase:
                if c2 >= c1:
                    break
                d = min(ord(c1) - ord(c2), 26 - ord(c1) + ord(c2))
                if d <= k:
                    cs[i] = c2
                    k -= d
                    break
        return "".join(cs)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution {
    public String getSmallestString(String s, int k) {
        char[] cs = s.toCharArray();
        for (int i = 0; i < cs.length; ++i) {
            char c1 = cs[i];
            for (char c2 = 'a'; c2 < c1; ++c2) {
                int d = Math.min(c1 - c2, 26 - c1 + c2);
                if (d <= k) {
                    cs[i] = c2;
                    k -= d;
                    break;
                }
            }
        }
        return new String(cs);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution {
public:
    string getSmallestString(string s, int k) {
        for (int i = 0; i < s.size(); ++i) {
            char c1 = s[i];
            for (char c2 = 'a'; c2 < c1; ++c2) {
                int d = min(c1 - c2, 26 - c1 + c2);
                if (d <= k) {
                    s[i] = c2;
                    k -= d;
                    break;
                }
            }
        }
        return s;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
func getSmallestString(s string, k int) string {
    cs := []byte(s)
    for i, c1 := range cs {
        for c2 := byte('a'); c2 < c1; c2++ {
            d := int(min(c1-c2, 26-c1+c2))
            if d <= k {
                cs[i] = c2
                k -= d
                break
            }
        }
    }
    return string(cs)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function getSmallestString(s: string, k: number): string {
    const cs: string[] = s.split('');
    for (let i = 0; i < s.length; ++i) {
        for (let j = 97; j < s[i].charCodeAt(0); ++j) {
            const d = Math.min(s[i].charCodeAt(0) - j, 26 - s[i].charCodeAt(0) + j);
            if (d <= k) {
                cs[i] = String.fromCharCode(j);
                k -= d;
                break;
            }
        }
    }
    return cs.join('');
}

评论