字符串数值题库
题一、具有给定数值的最小字符串
小写字符的数值是它在字母表中的位置(从 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"
方案A、贪心
思路: 因为需要的是字典序最小,所以优先使用a
拼接字符串,如果后面需要补充的长度使用z
无法达到k
值,则当前字符就不能使用a
拼接。如 n=3
,k=27
,优先使用a
拼接
-
当前第
1
个位置,如果使用a
,后面需要补充的是3-1
个z
,(3-1)*26=52 >= 27-1
,所以可以使用a
,此时s='a'
-
当前第
2
个位置,如果使用a
,后面需要补充的是3-2
个z
,(3-2)*26=26 >= 27-2
,所以可以使用a
,此时s='aa'
-
当前第
3
个位置,如果使用a
,后面需要补充的是3-3
个z
,(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');
}