LeetCode14. python實現:最長公共前綴問題☆

目錄

問題

解題思路

python具體實現

1.暴力實現

 2.二分查找實現

題外話


問題

編寫一個函數來查找字符串數組中的最長公共前綴。

如果不存在公共前綴,返回空字符串 ""


示例 1:

輸入: ["flower","flow","flight"]
輸出: "fl"

示例 2:

輸入: ["dog","racecar","car"]
輸出: ""
解釋: 輸入不存在公共前綴。

說明:

所有輸入只包含小寫字母 a-z 。


解題思路

    分析

1)一種最簡單的實現方法,即暴力實現:隨便選擇數組中的一個元素,操作簡單期間,就以數組中的第一個元素來作爲比較的基準;然後遍歷比較該元素中的每個字符和剩餘元素進行比較,一旦不符合公共前綴,立刻返回當前記錄的最長公共前綴;否則遍歷一遍,更新記錄的最長公共前綴。

三點注意:

  1.  數組爲空的情況:返回空值("")即可
  2.  數組只有一個元素的情況:則這一個元素即爲最長公共前綴
  3.  數組越界的情況:因爲我們是隨便選取的數組中的一個元素爲基準(而非數組中最短的元素爲基準)。因此,循環中的停止原則,除了字符不相等外,還有數組越界情況的處理。

補充:暴力實現的一種簡單改進就是選取數組中元素最短的作爲基準,具體實現改進很簡單,就不具體補充了!

2)二分查找實現

     基本原理同暴力實現,只是最初的比較對象,由基準元素的一個一個比較,變爲基準元素的前一半進行比較,這裏實現選取的基準元素改爲數組中的最短元素

注意:

  1. 左指針還是右指針移動的標記的設置,即實現中的flag變量
  2. 遍歷結束,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!一遍通過 

    對於二分查找實現,確實還是需要動下腦筋的。

   看似簡單的問題,或許並不簡單。參看下圖的程序運行時間,二分查找實現的效率相比暴力法的效率,提高了不止三分之一,由此也可見算法的重要性!

 

發佈了69 篇原創文章 · 獲贊 19 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章