LeetCode详解系列的总目录(持续更新中):LeetCode详解之如何一步步优化到最佳解法:前100题目录(更新中...)-CSDN博客
LeetCode详解系列的上一题链接:LeetCode详解之如何一步步优化到最佳解法:13. 罗马数字转整数-CSDN博客
目录
14. 最长公共前缀
解法1:暴力解法
代码
解法性能
解法分析
解法2:最终版
代码
解法性能
解法分析
14. 最长公共前缀
本题题目链接:14. 最长公共前缀 - 力扣(LeetCode)
解法1:暴力解法
代码
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
the_result = ""
for i, current_character in enumerate(strs[0]):
for j, current_str in enumerate(strs):
if len(current_str) < (i+1) or current_str[i] != current_character:
return the_result
the_result += current_character
return the_result
解法性能
解法分析
首先,了解题目中的给定条件是一件很重要的事。题目给出了三个提示,其中,第1个提示表明,这个strs列表至少含有一个字符串(注意:可能这仅有的字符串是空字符串);第2个提示表明,列表中任何一个字符串都有可能为空字符串;第3个提示表明,只要字符串不是空字符串的话,它就由小写字母组成。
然后,既然我们需要确定最长的公共前缀,那我们就从每一个字符串的第1个字符(第1列)开始,一个字符一个字符比较(可以理解为一种纵向比较,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同),对应的代码如下所示:
for i, current_character in enumerate(strs[0]):
for j, current_str in enumerate(strs):
若某一个字符串当前列的字符和之前所有的字符串当前列的字符不一样时,当前所存储的公共前缀就是最长的公共前缀;若是这一列遍历完,则将这一列对应的字符添加到我们存储的公共前缀变量”the_result”中。当然,这里面有一个要注意的点,就是对于我们正在比较的第i列,不是每一个字符串都有第i列的(即某些字符串的字符数小于等于i),在这种情况下,我们直接返回当前所存储的公共前缀即可。这一部分对应的代码为:
for i, current_character in enumerate(strs[0]):
for j, current_str in enumerate(strs):
if len(current_str) < (i+1) or current_str[i] != current_character:
return the_result
the_result += current_character
如果我们遍历完所有的列后,还是没有提前退出函数的话,则当前所存储的公共前缀就是最长的公共前缀。
接着,我们看看有哪些地方可以被优化的。首先,如果满足一些条件的话,可以提前退出。比如,如果列表strs只有1个字符串的话,则仅有的字符串就是最长的公共前缀(不管是不是空字符串,都是最长的公共前缀);还有,若是有空的字符串的话,也可以提前退出,返回空字符串。第二点可以优化的地方是解法1代码中的”len(current_str)”部分,我们可以看到”len(current_str)”这个计算是在for循环”for i, current_character in enumerate(strs[0]):”里面的,所以,除了第一个字符串以外的所有字符串,平均下来,其长度几乎都被算了很多遍(虽然,python也许对这块有优化)。这是一个可以节省时间的点,尤其是输入的列表中元素很多的情况下。我们可以提前将所有字符串的长度计算一遍并存储下来,方便我们在后面使用最短的时间来查询。
经过上面3点的优化,我们可以得到下面的解法:
解法2:最终版
代码
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
the_result = ""
if len(strs) == 1:
return strs[0]
all_length = []
for current_str in strs:
if len(current_str) != 0:
all_length.append(len(current_str))
else:
return the_result
for i, current_character in enumerate(strs[0]):
for j, current_str in enumerate(strs):
if all_length[j] < (i+1) or current_str[i] != current_character:
return the_result
the_result += current_character
return the_result
解法性能
解法分析
从上面的代码中,我们可以看到,首先,我们对只有一个字符串的情况进行了单独的处理。然后,我们使用一个列表”all_length”来记录所有字符串的长度,如果在记录的过程中,发现某一个字符串为空字符串的话,提前结束,直接返回空字符串。最后的嵌套for循环则和前面相似,只是不需要每次再计算一下当前字符串的长度了。
最后,前100题中,大家如果对哪些题目的详解比较感兴趣,可以在评论区留言,我会优先更新这些题目(我会优先选择简单和中等难度的题目),感谢大家的支持!!!