题目
刷题做到力扣 3014,题目要求设计电话键盘上的按键映射,返回按出 word 单词的最小按键次数,1 ≤ word.length ≤ 26,且仅由小写英文字母组成,所有字母互不相同
我的题解
简单题,略加思索拿下:
public int minimumPushes(String word) {
// 1 <= word.length <= 26
if (word.length() <= 8) return word.length();
else if (word.length() <= 16) return 8 + 2 * (word.length() - 8);
else if (word.length() <= 24) return 8 + 16 + 3 * (word.length() - 16);
else return 8 + 16 + 24 + 4 * (word.length() - 24);
}
这是一个基于条件逻辑的解决方案,很朴素
其他题解中关于易读性的思考
提交,看看别人的题解:
public int minimumPushes(String word) {
int n = word.length();
int k = n / 8;
return (k * 4 + n % 8) * (k + 1);
}
?这个题解显然是更简洁的,但我数学不好,确实没办法一次性读懂(在已经理解题目的前提下)
于是阅读题解的说明,原来是利用了求和公式:
8 ⋅ (1 + 2 + ⋯ + k) = 4k (k + 1)
由上,在加上剩余的 n mod 8 个字母需要按下的 k + 1 次,得到答案:
4k (k + 1) + (n mod 8)(k + 1) = (4k + n mod 8)(k + 1)
作为力扣的算法题解,数学的部分在文章里说明白了即可,代码中不带注释也正常。而我想在实践中写这样的代码时,是需要补充对公式化简的注释说明的,因此在这里抛砖引玉,先给出我的改进:
public int minimumPushes(String word) {
int n = word.length();
int k = n / 8;
// 8 * (1 + 2 + ... + k) + (n % 8) * (k + 1) = (k * 4 + n % 8) * (k + 1)
return (k * 4 + n % 8) * (k + 1);
}
GPT-4 的简化
另外,附上 GPT-4 对题解的简化结果,我认为是相对更晦涩的,不建议采用:
public int minimumPushes(String word) {
int length = word.length();
if (length <= 8) return length;
int basePushes = 8; // 第一个8字符需要8次按键
length -= 8; // 减去第一部分的长度
int extraPushes = 2; // 超过8个字符后,每增加1个字符,按键次数增加的倍数从2开始
while (length > 8) {
basePushes += 8 * extraPushes; // 按当前倍数增加按键次数
length -= 8; // 减去处理过的长度
extraPushes++; // 增加倍数
}
basePushes += length * extraPushes; // 处理剩余长度
return basePushes;
}