我从用户那里获得自定义字符串。现在我需要设计最短路径,在包含9个按钮的键盘中按下该字符串。
注意:
解决方案,如果输入text ='hello'
或者
使用此键盘我需要按“3,2,4,4,5”键入“hello”
因此,如果您想使用此设计的键盘输入'hello',您只需按下5个键盘按钮,因为这是最少的键数。
我认为这个问题是用贪婪的方法或回溯算法解决的。
答案 0 :(得分:3)
让我们将字母表推广到{1,...,n}。设k是键的数量。对于1≤i<1。 j≤k,可能键{i,...,j}的成本(=按下次数)为1f i + 2f i + 1 + ... +(j - i + 1)f j ,其中f i 是字母i的频率。我们正在寻找由k个密钥组成的最低成本精确覆盖。
此问题具有以下最佳子结构:修复任意最优解并删除其上带有{m + 1,...,n}的密钥。结果是k - 1键和字母{1,...,m}问题的最优解;否则,我们可以通过重新排列第一个k-1键来改进第一个最佳解决方案。
因此,我们可以应用动态编程。对于每0≤i≤n且每0≤j≤k,使用j键计算{1,...,i}的最佳排列。这种安排C i,j 的成本满足复发
对于所有j≥0, C 0,j = 0
对于所有i> C i,0 =∞; 0
C i,j = min 0≤i'&lt;我(C i',j-1 + c i',j ),
其中c a,b 是密钥{a,...,b}的成本。人们可以从最佳参数序列中恢复这种安排。
答案 1 :(得分:2)
每个有效的键盘对应一个26位数字,正好有9位设置为1.只有2042975个有效组合要尝试,在其他需要更多思考的方法之前,暴力应该是首先尝试的。算法就像这个伪代码:
int best_score = int.max
list<int> keypads
for int mask between 1 and 1<<26
if bit_count(mask) != 9 or mask ends in 1 continue
int lookup[26]
int p = 1
for int i between 0 and 26
lookup[i] = p
if mask's bit i is set to 1, p = 1 ; otherwise, p = p + 1
int total = 0
for each char ch in word
total = total + lookup[ch]
if total < best
keypads = new list {mask}
best = total
else if total == best
keypads.add(mask)
print best, keypads