跳到主要内容

字符串数值题库

题一、具有给定数值的最小字符串


小写字符的数值是它在字母表中的位置(从 1 开始),因此 a 的数值为 1b 的数值为 2c 的数值为 3 ,以此类推。字符串由若干小写字符组成,字符串的数值为各字符的数值之和。例如,字符串abe的数值等于1 + 2 + 5 = 8。给你两个整数 nk 。返回长度等于 n 且 数值等于 k 的字典序最小的字符串。

注意,如果字符串 x 在字典排序中位于 y 之前,就认为 x 字典序比 y 小,有以下两种情况:

  • xy 的一个前缀

  • 如果 ix[i] != y[i] 的第一个位置,且 x[i] 在字母表中的位置比 y[i] 靠前

示例1:

输入:n = 3, k = 27
输出:"aay"
解释:字符串的数值为 1 + 1 + 25 = 27,它是数值满足要求且长度等于 3 字典序最小的字符串。

示例2:

输入:n = 5, k = 73
输出:"aaszz"

方案A、贪心

思路: 因为需要的是字典序最小,所以优先使用a拼接字符串,如果后面需要补充的长度使用z无法达到k值,则当前字符就不能使用a拼接。如 n=3,k=27,优先使用a拼接

  1. 当前第1个位置,如果使用a,后面需要补充的是3-1z(3-1)*26=52 >= 27-1,所以可以使用a,此时s='a'

  2. 当前第2个位置,如果使用a,后面需要补充的是3-2z(3-2)*26=26 >= 27-2,所以可以使用a,此时s='aa'

  3. 当前第3个位置,如果使用a,后面需要补充的是3-3z(3-3)*26=0 < 27-3,所以第3个位置不能使用a,应使用当前的差值的绝对值((3-2)*26-27-2)

实现

function getSmallestString(n,k){
let s = '';
let num = 0;
for(let i=0;i<n;i++){
let diff = (n-i-1)*26 - (k-num);
if(diff >= 0){
s += 'a';
num++;
}else{
let code = Math.abs(diff);
num += code;
s += String.fromCharCode(code+96);
break;
}
}
return s.padEnd(n,'z');
}