与T2类似,只不过多了一个限定条件 k,可以使用试填法,枚举每一位可以选择的字符,盘算如果当前选择字符 a,出现的所有排列 p,与 k 进行比较:
p >= k,说明当前可以选择字符 a
p < k,说明当前不能选择字符 a,继续枚举字符
本题的难点在于盘算 ( n m ) \binom{n}{m} (mn),不能先预处理 n! 再去盘算,因为可能会出现越界,这里有两种做法:
根据选或不选,可以得到公式 ( n m ) = ( n − 1 m ) + ( n − 1 m − 1 ) \binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1} (mn)=(mn−1)+(m−1n−1),根据该公式去盘算 ( n m ) \binom{n}{m} (mn),由于是加法运算,不会溢出,如果 > k,可以直接返回 k.
( n m ) = n ! m ! ( n − m ) ! = n ∗ ( n − 1 ) ∗ . . . ∗ ( n − m + 1 ) 1 ∗ 2 ∗ . . . ∗ m \binom{n}{m} = \frac{n!}{m!(n-m)!}= \frac{n*(n-1)*...*(n-m+1)}{1*2*...*m} (mn)=m!(n−m)!n!=1∗2∗...∗mn∗(n−1)∗...∗(n−m+1),可以分开盘算 n / 1 ∗ ( n − 1 ) / 2 ∗ ( n − 3 ) / 3 ∗ . . . n/1*(n-1)/2*(n-3)/3*... n/1∗(n−1)/2∗(n−3)/3∗...,如许也可以避免溢出。
代码如下:
class Solution {
public String smallestPalindrome(String s, int k) {