leetcode1663.具有给定数值的最小字符串 | 刷题打卡

301 阅读1分钟

题目描述

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;
};

image.png

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情