目錄
問題
編寫一個函數來查找字符串數組中的最長公共前綴。
如果不存在公共前綴,返回空字符串 ""
。
示例 1:
輸入: ["flower","flow","flight"]
輸出: "fl"
示例 2:
輸入: ["dog","racecar","car"]
輸出: ""
解釋: 輸入不存在公共前綴。
說明:
所有輸入只包含小寫字母 a-z
。
解題思路
分析:
1)一種最簡單的實現方法,即暴力實現:隨便選擇數組中的一個元素,操作簡單期間,就以數組中的第一個元素來作爲比較的基準;然後遍歷比較該元素中的每個字符和剩餘元素進行比較,一旦不符合公共前綴,立刻返回當前記錄的最長公共前綴;否則遍歷一遍,更新記錄的最長公共前綴。
三點注意:
- 數組爲空的情況:返回空值("")即可
- 數組只有一個元素的情況:則這一個元素即爲最長公共前綴
- 數組越界的情況:因爲我們是隨便選取的數組中的一個元素爲基準(而非數組中最短的元素爲基準)。因此,循環中的停止原則,除了字符不相等外,還有數組越界情況的處理。
補充:暴力實現的一種簡單改進就是選取數組中元素最短的作爲基準,具體實現改進很簡單,就不具體補充了!
2)二分查找實現
基本原理同暴力實現,只是最初的比較對象,由基準元素的一個一個比較,變爲基準元素的前一半進行比較,這裏實現選取的基準元素改爲數組中的最短元素。
注意:
- 左指針還是右指針移動的標記的設置,即實現中的flag變量
- 遍歷結束,mid的值就是元素minElement中最長前綴的停止位置(不包含mid所在位置)
根據上述分析,詳細實現參看程序即可。
python具體實現
1.暴力實現
class Solution(object):
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
# 特殊情況的處理
if len(strs)<1: # 空數組
return ""
if len(strs) ==1: # 數組只有一個元素
return strs[0]
commonStr = "" # 存儲最長公共前綴
for i in range(len(strs[0])):
for j in range(1,len(strs)):
if i>len(strs[j])-1 or strs[0][i] != strs[j][i]: #兩種不符合前綴的停止條件
return commonStr
commonStr = commonStr + strs[0][i] # 前綴的添加
return commonStr
2.二分查找實現
class Solution(object):
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
# 特殊情況的處理
if len(strs)<1: # 空數組
return ""
if len(strs) ==1: # 數組只有一個元素
return strs[0]
minElement = strs[0]
for i in range(len(strs)): # 遍歷獲取數組中的最短元素
if len(strs[i])<len(minElement):
minElement = strs[i]
# 二分查找實現部分
left = 0
right =len(minElement)
mid = (left+right)//2
while left<right:
flag = True # 左指針還是右指針移動 默認左指針
for j in range(len(strs)):
if minElement[:mid+1] != strs[j][:mid+1]: 不符合前綴的停止條件
right = mid
flag = False
break
if flag :
left = mid+1
mid = (left+right)//2
return minElement[:mid] #遍歷結束,mid位置就是截取的停止下一位置
題外話
如果採用暴力實現,Take easy!一遍通過
對於二分查找實現,確實還是需要動下腦筋的。
看似簡單的問題,或許並不簡單。參看下圖的程序運行時間,二分查找實現的效率相比暴力法的效率,提高了不止三分之一,由此也可見算法的重要性!