题目描述补充
题目:排列序号Ⅱ
给定一个字符串 s
和一个整数 k
,其中 s
仅由小写英文字母组成,表示一个未完成的排列。我们需要在 s
的基础上,通过插入恰好 k
个未在 s
中出现过的最小字母(按字母顺序),使得结果字符串是一个完整的排列(即包含所有小写英文字母恰好一次)。返回所有可能的完整排列的第 k
个排列的字符串。
注意:
- 输入的
s
不包含重复字符。 k
的取值范围在1
到26 - s.length
之间(包括边界值)。- 题目保证至少存在一个有效的完整排列,使得第
k
个排列存在。
示例
输入:
s = "abc"
k = 3
输出:
"ahfbcd"
解释:
- 未完成的排列
"abc"
缺少d
,e
,f
,g
, ...,z
这些字母。 - 插入这些字母后的所有可能排列中,第
3
个排列是"ahfbcd"
。
PHP 示例代码
function getPermutation($s, $k) {
$n = strlen($s);
$remaining = 26 - $n; // 剩余需要插入的字母数量
$total = 1; // 初始排列数
// 计算在s的每个位置后插入新字母能形成的排列总数
for ($i = 0; $i < $n; $i++) {
$total *= ($remaining + 1 - $i);
}
// 确定第k个排列的起始位置
$index = 0;
while ($k > $total) {
$k -= $total;
$total /= ($remaining--);
$index++;
}
// 构建第k个排列
$result = '';
$inserted = 0; // 已插入的字母数量
for ($i = 0; $i < $n; $i++) {
$curTotal = ($remaining - $inserted) * factorial($remaining - $inserted - 1);
if ($k <= $curTotal) {
$result .= $s[$i];
} else {
$k -= $curTotal;
$result .= chr(ord('a') + $inserted);
$inserted++;
}
}
// 插入剩余的字母
for ($i = ord('a'); $i <= ord('a') + $remaining - 1; $i++) {
if ($inserted < $remaining) {
$result .= chr($i);
$inserted++;
}
}
return $result;
}
function factorial($n) {
$result = 1;
for ($i = 2; $i <= $n; $i++) {
$result *= $i;
}
return $result;
}
// 示例调用
echo getPermutation("abc", 3); // 输出 ahfbcd
注意:上述PHP代码是一个简化的版本,用于说明算法思路,并未完全优化性能(如计算阶乘和排列数时)。在真实面试中,可能需要更高效的算法或使用数据结构来优化性能。
码小课
码小课网站中有更多相关内容分享给大家学习,涵盖算法、数据结构、编程语言等多个方面,帮助大家提升编程能力和解决复杂问题的能力。