class Solution:
def getSmallestString(self, n: int, k: int) -> str:
res = ['a'] * n
k -= n # since each 'a' already contributes 1
idx = n - 1
while k > 0:
add = min(25, k)
res[idx] = chr(ord('a') + add)
k -= add
idx -= 1
return ''.join(res)
class Solution {
public:
string getSmallestString(int n, int k) {
string res(n, 'a');
k -= n;
int idx = n - 1;
while (k > 0) {
int add = min(25, k);
res[idx] = 'a' + add;
k -= add;
idx--;
}
return res;
}
};
class Solution {
public String getSmallestString(int n, int k) {
char[] res = new char[n];
for (int i = 0; i < n; i++) res[i] = 'a';
k -= n;
int idx = n - 1;
while (k > 0) {
int add = Math.min(25, k);
res[idx] = (char)('a' + add);
k -= add;
idx--;
}
return new String(res);
}
}
var getSmallestString = function(n, k) {
let res = Array(n).fill('a');
k -= n;
let idx = n - 1;
while (k > 0) {
let add = Math.min(25, k);
res[idx] = String.fromCharCode('a'.charCodeAt(0) + add);
k -= add;
idx--;
}
return res.join('');
};
Given two integers n
and k
, your task is to construct the lexicographically smallest string of length n
using only lowercase English letters ('a' to 'z'), such that the sum of the numeric values of its characters is exactly k
. The numeric value of a letter is its position in the alphabet (i.e., 'a' = 1, 'b' = 2, ..., 'z' = 26).
At first glance, the problem seems to ask for the smallest possible string (alphabetically) whose letters add up to a given value. The brute-force way would be to try all possible combinations, but that is clearly inefficient for large n
and k
.
To minimize the string lexicographically, we should put the smallest letters ('a') at the front as much as possible. If we need larger values to reach k
, we should place them at the end so that the beginning of the string remains as small as possible.
The key realization is that we can "fill" the string from the end with the largest possible letters (up to 'z'), using 'a' by default, and only increase the value of the last few letters as needed to reach the target sum.
n
positions. This gives a starting sum of n
(since each 'a' is worth 1).k
: remaining = k - n
.This approach ensures that the string is as small as possible lexicographically, since any larger letters are pushed to the end.
Let's walk through an example with n = 5
and k = 73
:
res = ['a', 'a', 'a', 'a', 'a']
(sum = 5).'aaszz'
.This is the lexicographically smallest string of length 5 with a numeric value of 73.
n
and checking their values, which is O(26^n)
— clearly infeasible for large n
.
O(n)
.n
to build the string, so the space complexity is also O(n)
.The optimized approach is efficient and works well within the problem's constraints.
The problem boils down to distributing the required numeric value across the string in a way that keeps it lexicographically smallest. By filling with 'a's and only increasing values from the end as needed, we ensure the smallest possible string. The approach is both simple and efficient, requiring only a single pass and minimal extra space. This method elegantly leverages the properties of lexicographical order and greedy allocation.