首先采用一般做法,就是对LIST里面的string做纵向的比较。一直比到其中一个string不符合–过短,或者字符不对。
逻辑比较复杂。temp是第一个string,在offset K的值。虽然复杂,还是一次过了。
我的代码如下:
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
k = 0 # offset in string
result = ""
while True:
match = True
seq = 0 # sequence in the list
for s in strs:
if k>=len(s):
match = False
break
if seq==0:
temp = s[k]
seq += 1
continue
if s[k]!=temp:
match = False
break
k+=1
if seq>0 and match:
result += temp
else:
break # from while
return result
Youtube里https://www.youtube.com/watch?v=cGQez9SiScw&list=PL2rWx9cCzU84eBz9Xfp9Rah5Fexq5yrh8&index=5
Michelle小梦想家讲了个比较巧妙的方法,框架和上面是类似的,但是使用了python里面的set,来做list里面元素间在某个offset的比较。
- 用了try/except来handle各种越界的问题
- 用了set这个构造,set(string[k] for string in strs)
- Python好像自己的函数优化的不错,比自己通常写的要效率高。但也许是因为上面的代码有更多行,interpreted比较慢的缘故。
- 上面的完全是访问,没有构造set这种数据结构,应该在内存使用上比较直接的。(优点)
- 这个方案beat 90%的提交,速度不错。
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
k = 0 # offset in string
result = ""
while True:
try:
s = set(string[k] for string in strs) # kth char of each list element
if len(s) == 1:
result += s.pop()
k+=1
else:
break;
except Exception as e: # for index out of bound error, etc
break
return result
还有一种是用第一个元素和其它元素比较,和我的第一种做法类似,但写法好很多,直接循环第一个元素string里的字符。
也能beat 90%
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
result = ""
if len(strs) == 0:
return ""
for i in range(len(strs[0])):
unmatched = False
for string in strs[1:]:
if i>=len(string) or string[i] != strs[0][i]:
unmatched = True
break;
if unmatched:
break
else:
result += strs[0][i]
return result
最后是不连接字符串的,而是返回str[0][:i].
方法非常巧妙,但是速度好像不行。和第一种一样。
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
result = ""
if len(strs) == 0:
return ""
for i in range(len(strs[0])):
for string in strs[1:]:
if i>=len(string) or string[i] != strs[0][i]:
return strs[0][:i] #<--------------- here
# the case that only strs[0] exists and can't compare with others
# or completely match
return strs[0]