LeetCode Notes_#14 Longest Common Prefix
LeetCode Notes_#14 Longest Common Prefix
Contents
Problem
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string "".
Example 1:
Input: ["flower","flow","flight"]
Output: "fl"
Example 2:
Input: ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
Solution
思路
寻找最长的公共前缀,我的想法是直接从第一个字母开始遍历,设置一个flag代表是否有共同的前缀。
#try:截取一个字符串的一部分
a='string'
a[0:2]
'st'
- #遇到一个大小写问题,意识到动态语言的缺点了...
- Input=["flower","flow","flight"]
- InputLen=[]
- MinLen=0
- flag=1
- TmpList=[]#用于存储每个字符串的前缀
- for i in range(len(Input)):
- InputLen.append(len(Input[i]))
- MinLen=min(InputLen)
- for j in range(1,MinLen):
- # print(flag)
- TmpList=[]
- if flag:#前面的前缀相同了,我才继续往后去尝试
- for k in range(len(Input)):#遍历每个单词
- TmpList.append(Input[k][0:j])#依次取每个单词的前面j个字符,加入列表
- print(TmpList)
- if len(set(TmpList))!=1:
- flag=0#这时刚好开始出现不同,那么前j-1个相同
- print (Input[0][0:j-1])
-
['f', 'f', 'f']
['fl', 'fl', 'fl']
['flo', 'flo', 'fli']
fl
#一些corner case,emmmm
[]
[""]
["",""]
["a","aa"]
["c","c"]
[""][0]#这种情况就不可以用二重下标了
''
'a'[0]
'a'
'a'[0:1]
'a'
解答
- class Solution(object):
- def longestCommonPrefix(self, strs):
- """
- :type strs: List[str]
- :rtype: str
- """
- if strs==[]:
- return ''
- if '' in strs:
- return ''
- if len(strs)==1:
- return strs[0]
- if len(set(strs))==1:
- return strs[0]
-
- InputLen=[]
- MinLen=0
- flag=1
- TmpList=[]#用于存储每个字符串的前缀
- for i in range(len(strs)):
- InputLen.append(len(strs[i]))
- MinLen=min(InputLen)
- # print MinLen
- # print range(1)
- for j in range(MinLen):
- # print(flag)
- TmpList=[]
- if flag:#前面的前缀相同了,我才继续往后去尝试
- for k in range(len(strs)):#遍历每个单词
- TmpList.append(strs[k][0:j+1])#依次取每个单词的前面j个字符,加入列表
- # print(TmpList)
- # print j,k,TmpList
- # print len(set(TmpList))
- if len(set(TmpList))!=1:
- flag=0#这时刚好开始出现不同,那么前j-1个相同
- # print j
- if j>=1:
- return strs[0][0:j]
- else:
- return ''
- elif (len(set(TmpList))==1 and j==MinLen-1):
- return TmpList[0]
28ms,faster than 57.76%
这些corner case有点烦人...这代码有点辣鸡,很多的for还有if else...
高票答案
- class Solution:
- # @return a string
- def longestCommonPrefix(self, strs):
- if not strs:
- return ""
-
- for i, letter_group in enumerate(zip(*strs)):
- if len(set(letter_group)) > 1:
- return strs[0][:i]
- else:
- return min(strs)
看看人家这个代码多优雅...用了一些python中比较高级的用法。
所以所谓精通一门语言,就是要会使用这门语言里边特有的一些用法去缩短代码,提高效率,提高可读性。
而不是说每一门语言我都只会用最基本的循环,if...else...解决问题,那样就没有了深入学习一门语言的意义。
- enumerate()
Python 内置的 enumerate 函数可以把一个 list 变成索引-元素对,这样就
可以在 for 循环中同时迭代索引和元素本身
for i, value in enumerate(['A', 'B', 'C']):
print(i, value)
0 A
1 B
2 C
- zip()
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。
我们可以使用 list() 转换来输出列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
strs=["asd","sdfa"]
list(zip(*strs))
[('a', 's'), ('s', 'd'), ('d', 'f')]
Java
更好的思路是纵向比较,即外层循环是元素下标,内层循环是strs
数组的下标。比较strs
数组当中每个字符串相同位置是字符是否相同,遇到不同的,说明在此之前的子字符串就是最长的公共前缀。
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs == null || strs.length == 0) return "";
int arrayLength = strs.length;
int firstStrLength = strs[0].length();
for(int i = 0;i < firstStrLength;i++){
char c = strs[0].charAt(i);
for(int j = 0;j < arrayLength;j++){
if(i == strs[j].length() || strs[j].charAt(i) != c){
return strs[0].substring(0, i);
}
}
}
return strs[0];
}
}