题目描述
leetcode链接:leetcode-cn.com/problems/sm…
小写字符 的 数值 是它在字母表中的位置(从 1 开始),因此 a 的数值为 1 ,b 的数值为 2 ,c 的数值为 3 ,以此类推。 字符串由若干小写字符组成,字符串的数值 为各字符的数值之和。例如,字符串 "abe" 的数值等于 1 + 2 + 5 = 8 。 给你两个整数 n 和 k 。返回 长度 等于 n 且 数值 等于 k 的 字典序最小 的字符串。 注意,如果字符串 x 在字典排序中位于 y 之前,就认为 x 字典序比 y 小,有以下两种情况:
- x 是 y 的一个前缀;
- 如果 i 是 x[i] != y[i] 的第一个位置,且 x[i] 在字母表中的位置比 y[i] 靠前。
示例1:
输入:n = 3, k = 27
输出:"aay"
解释:字符串的数值为 1 + 1 + 25 = 27,它是数值满足要求且长度等于 3 字典序最小的字符串。
实例2:
输入:n = 5, k = 73
输出:"aaszz"
提示:
- 1 <= n <= 105
- n <= k <= 26 * n
思路描述
使用的是贪心算法的思想。这道题我觉得挺难的。我想不到怎么做,思路是搬运题解中的做法。
由于我们要使得构造出的字符串字典序最小,因此可以考虑贪心地从字符串的开头处开始构造,每次选择一个满足要求的最小的字母,即可得到最终答案。
这里我们用 k-26(n-1)这个公式来推导,假设 n-1 个字符都是 z ,还是比 k 小,即 k-26(n-1) > 0 ,那么第一个字符只能是 k-26(n-1) 对应的字符了。如果 k-26(n-1) <= 0 ,那么说明第一个字符可以是 a 。然后再进行递归获取第二个字符。依次类推。
AC代码
/**
* @param {number} n
* @param {number} k
* @return {string}
*/
var getSmallestString = function(n, k) {
let rest = n;
let str = "";
while(rest) {
const temp = k - 26 * (rest - 1);
if (temp > 0) {
str += String.fromCharCode('a'.charCodeAt() + temp - 1)
k -= temp
} else {
str += "a"
k--
}
rest--;
}
return str;
};
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情