[LeetCode解題攻略] 14. Longest Common Prefix

更新於 2024/12/24閱讀時間約 8 分鐘

題目描述

給定一組字符串,找出它們的最長公共前綴 (Longest Common Prefix)。如果沒有公共前綴,返回空字串 ""

範例 1

Input: strs = ["flower", "flow", "flight"]
Output: "fl"

    • 這些字符串的公共前綴為 "fl"

範例 2

Input: strs = ["dog", "racecar", "car"]
Output: ""

    • 這些字符串之間沒有公共前綴,返回 ""

解題思路

解決這個問題的關鍵在於如何高效地縮小範圍,找到最長公共前綴。以下列出常見的解法:

  1. 水平掃描法
    將第一個字符串作為基準,依次與後面的字符串比較並縮小公共前綴的長度。
  2. 垂直掃描法
    逐列掃描每個字符串,檢查每列的字符是否相同。如果發現不一致,立即結束。
  3. 分治法
    將字符串數組分為兩部分,遞歸地找出每部分的最長公共前綴,然後合併。
  4. 二分查找法
    以最短字符串的長度作為搜索範圍,使用二分查找法判斷某個長度是否為公共前綴。

解法 1:水平掃描法

思路

  • 將第一個字符串作為初始公共前綴,依次與其他字符串比較並縮短公共前綴,直到匹配完成或前綴為空。

實現 (Python)

class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""

# 初始化 prefix 為第一個字符串
prefix = strs[0]

for s in strs[1:]:
# 縮短 prefix,直到找到公共部分
while not s.startswith(prefix):
prefix = prefix[:-1]
if not prefix:
return ""

return prefix

時間與空間複雜度

  • 時間複雜度:O(S),其中 S 是所有字符串字符的總數。最壞情況下,我們需要遍歷所有字符串的每個字符。
  • 空間複雜度:O(1),只需要額外的變量來存儲前綴。

解法 2:垂直掃描法

思路

  • 逐列掃描每個字符串,檢查是否所有字符串在相同位置的字符一致。一旦發現某列字符不同,立即返回當前的公共前綴。

實現 (Python)

class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""

for i in range(len(strs[0])):
char = strs[0][i]
for s in strs[1:]:
# 如果超出長度或字符不匹配,結束掃描
if i >= len(s) or s[i] != char:
return strs[0][:i]

return strs[0]

時間與空間複雜度

  • 時間複雜度:O(S),同樣需要檢查所有字符。
  • 空間複雜度:O(1)。

解法 3:分治法

思路

  • 將字符串數組分成兩部分,遞歸地找出每部分的最長公共前綴,然後合併兩部分的結果。

實現 (Python)

class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""

def commonPrefix(left, right):
min_len = min(len(left), len(right))
for i in range(min_len):
if left[i] != right[i]:
return left[:i]
return left[:min_len]

def divideAndConquer(strs, l, r):
if l == r:
return strs[l]
mid = (l + r) // 2
left_prefix = divideAndConquer(strs, l, mid)
right_prefix = divideAndConquer(strs, mid + 1, r)
return commonPrefix(left_prefix, right_prefix)

return divideAndConquer(strs, 0, len(strs) - 1)

時間與空間複雜度

  • 時間複雜度:O(S),每次遞歸都需要比較兩部分的前綴。
  • 空間複雜度:O(log(N)),其中 N 是字符串數組的大小,遞歸的深度最多為 log(N)。

解法 4:二分查找法

思路

  • 將最短字符串的長度作為二分查找的搜索範圍。
  • 每次檢查中間長度是否為公共前綴,並根據結果縮小範圍。

實現 (Python)

class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""

def isCommonPrefix(length):
prefix = strs[0][:length]
return all(s.startswith(prefix) for s in strs)

min_len = min(len(s) for s in strs)
low, high = 0, min_len

while low < high:
mid = (low + high + 1) // 2
if isCommonPrefix(mid):
low = mid
else:
high = mid - 1

return strs[0][:low]

時間與空間複雜度

  • 時間複雜度:O(S × log(M)),其中 M 是最短字符串的長度,S 是所有字符串字符的總數。
  • 空間複雜度:O(1)。

總結

最推薦的解法是水平掃描法垂直掃描法,因為它們簡單直觀且能高效地處理大多數情況。如果數據規模較大,且字符串的長度有較大差異,可以考慮分治法二分查找法進一步優化。


歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
給定一個包含 2 到 9 之間數字的字串,傳回該數字可以表示的所有可能的字母組合。以任意順序回傳答案。 參考附圖為數字對字母的映射(就像電話按鈕一樣)。
給定一個長度為 n 的整數數組 nums 和一個整數target,在 nums 中找到三個整數,使得總和最接近target。傳回三個整數的總和。可以假設每個輸入都有一個解決方案。
給定整數陣列nums,傳回所有三元組[nums[i], nums[j], nums[k]],使得i != j, i != k, j != k,且nums[i ] + nums[j] + nums[k] == 0。
在這篇文章中,我們將深入剖析 LeetCode 題目 13. Roman to Integer 的解題方法。這是一道經典題目,要求我們將羅馬數字轉換為整數表示。通過學習這篇教學,你將掌握如何處理羅馬數字的規則和高效地實現轉換。
在這篇文章中,我們將探討 LeetCode 題目 12. Integer to Roman 的解題方法。這是一道經典的模擬題,要求我們將整數轉換為羅馬數字表示。通過這篇文章,你將學會如何高效地解決這道題,並理解羅馬數字的基本規則和轉換技巧。
這篇文章將介紹 LeetCode 題目 11. Container With Most Water。這是一道經典的雙指針問題,題目要求我們找到容器可以盛最多水的情況,並幫助我們理解如何通過移動左右指針來最大化結果。
給定一個包含 2 到 9 之間數字的字串,傳回該數字可以表示的所有可能的字母組合。以任意順序回傳答案。 參考附圖為數字對字母的映射(就像電話按鈕一樣)。
給定一個長度為 n 的整數數組 nums 和一個整數target,在 nums 中找到三個整數,使得總和最接近target。傳回三個整數的總和。可以假設每個輸入都有一個解決方案。
給定整數陣列nums,傳回所有三元組[nums[i], nums[j], nums[k]],使得i != j, i != k, j != k,且nums[i ] + nums[j] + nums[k] == 0。
在這篇文章中,我們將深入剖析 LeetCode 題目 13. Roman to Integer 的解題方法。這是一道經典題目,要求我們將羅馬數字轉換為整數表示。通過學習這篇教學,你將掌握如何處理羅馬數字的規則和高效地實現轉換。
在這篇文章中,我們將探討 LeetCode 題目 12. Integer to Roman 的解題方法。這是一道經典的模擬題,要求我們將整數轉換為羅馬數字表示。通過這篇文章,你將學會如何高效地解決這道題,並理解羅馬數字的基本規則和轉換技巧。
這篇文章將介紹 LeetCode 題目 11. Container With Most Water。這是一道經典的雙指針問題,題目要求我們找到容器可以盛最多水的情況,並幫助我們理解如何通過移動左右指針來最大化結果。
你可能也想看
Google News 追蹤
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
題目敘述 Longest Palindromic Subsequence 給定一個字串s,請找出字串s的最長回文子序列的長度。 註: 子序列 不要求一定要連續。 測試範例 Input: s = "bbbab" Output: 4
Thumbnail
題目敘述 Longest Palindromic Substring 給定一個輸入字串s,請找出最長的回文子字串。 答案可能不只一個,回傳任何一個合法的答案皆可。
Thumbnail
給定一個字串陣列,請把它們所共有的字元伴隨著出現次數輸出。這篇文章介紹如何使用字典統計出現次數,和字典取交集的方法來解決此問題。並提供了複雜度分析和關鍵知識點。
Thumbnail
給定一個字串s,以s擁有的字元製造迴文字串。要能製造出的迴文字串長度最長是多少,觀察迴文字串不外乎兩種模式對稱部分 + 核心字元 + 對稱部分,其中,核心字元在正中央出現一次,或者 對稱部分 + 對稱部分。使用演算法統計出現次數並推理出盡可能充分利用每個字元的迴文字串製造方法。
Thumbnail
Append Characters to String to Make Subsequence 給定兩個字串s和字串t。 請計算最少的字元串接數量是多少,串接在s的尾端,使得t是s的子序列。 測試範例 Example 1: Input: s = "coaching", t =
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定兩個輸入字串str1和str2,要求我們找出這兩個字串的最大共同子字串。 如果無解,則返回空字串""。 題目的原文敘述 測試範例 Example 1: Input: str1 = "ABCABC", str2 = "ABC" Output: "ABC" Exam
Thumbnail
這題也是滿經典的DP動態規劃教學案例和題目,就順便複習一下吧。 題目敘述 題目會給我們兩個字串text1, text2。 要求我們找出兩個字串的最長共同子序列,並且返回最長共同子序列的長度。 如果彼此沒有共同子序列,則返回0。 題目的原文敘述 測試範例 Example 1: In
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
題目敘述 Longest Palindromic Subsequence 給定一個字串s,請找出字串s的最長回文子序列的長度。 註: 子序列 不要求一定要連續。 測試範例 Input: s = "bbbab" Output: 4
Thumbnail
題目敘述 Longest Palindromic Substring 給定一個輸入字串s,請找出最長的回文子字串。 答案可能不只一個,回傳任何一個合法的答案皆可。
Thumbnail
給定一個字串陣列,請把它們所共有的字元伴隨著出現次數輸出。這篇文章介紹如何使用字典統計出現次數,和字典取交集的方法來解決此問題。並提供了複雜度分析和關鍵知識點。
Thumbnail
給定一個字串s,以s擁有的字元製造迴文字串。要能製造出的迴文字串長度最長是多少,觀察迴文字串不外乎兩種模式對稱部分 + 核心字元 + 對稱部分,其中,核心字元在正中央出現一次,或者 對稱部分 + 對稱部分。使用演算法統計出現次數並推理出盡可能充分利用每個字元的迴文字串製造方法。
Thumbnail
Append Characters to String to Make Subsequence 給定兩個字串s和字串t。 請計算最少的字元串接數量是多少,串接在s的尾端,使得t是s的子序列。 測試範例 Example 1: Input: s = "coaching", t =
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定兩個輸入字串str1和str2,要求我們找出這兩個字串的最大共同子字串。 如果無解,則返回空字串""。 題目的原文敘述 測試範例 Example 1: Input: str1 = "ABCABC", str2 = "ABC" Output: "ABC" Exam
Thumbnail
這題也是滿經典的DP動態規劃教學案例和題目,就順便複習一下吧。 題目敘述 題目會給我們兩個字串text1, text2。 要求我們找出兩個字串的最長共同子序列,並且返回最長共同子序列的長度。 如果彼此沒有共同子序列,則返回0。 題目的原文敘述 測試範例 Example 1: In