返回

无处不在的 LeetCode 14:最长公共前缀,LeetCode 入门之选

前端

LeetCode 题海征途,从 14 开始

LeetCode,一个以难度闻名的编程题目平台,吸引了无数程序员前来挑战。作为 LeetCode 入门题目的代表,第 14 题——最长公共前缀,用看似简单的题目,考验着我们的算法思维和字符串处理能力。

从暴力到高效,三种解法横空出世

一、暴力解法:朴实无华,步步为营

暴力解法,顾名思义,就是用最直接的方法来解决问题。对于最长公共前缀,暴力解法就是逐个字符地比较字符串数组中的每个字符串,找到所有字符串都相同的公共前缀。

def longestCommonPrefix_brute_force(strs):
  """
  暴力解法:逐个字符比较字符串数组中的每个字符串,找到所有字符串都相同的公共前缀。

  Args:
    strs: 字符串数组

  Returns:
    最长公共前缀
  """

  # 如果字符串数组为空,则返回空字符串
  if not strs:
    return ""

  # 找到字符串数组中最短的字符串的长度
  min_len = min(len(s) for s in strs)

  # 逐个字符地比较字符串数组中的每个字符串
  for i in range(min_len):
    # 如果所有字符串的第 i 个字符都相同,则继续比较下一个字符
    if all(s[i] == strs[0][i] for s in strs):
      continue
    # 否则,返回第 i 个字符之前的子字符串作为最长公共前缀
    else:
      return strs[0][:i]

  # 如果所有字符串都相同,则返回整个字符串作为最长公共前缀
  return strs[0]

二、水平扫描法:化繁为简,一览众字符

水平扫描法,顾名思义,就是从左到右逐个扫描字符串数组中的每个字符,并记录所有字符串中出现过的字符。如果某个字符在所有字符串中都出现过,则将其添加到最长公共前缀中。

def longestCommonPrefix_horizontal_scanning(strs):
  """
  水平扫描法:从左到右逐个扫描字符串数组中的每个字符,并记录所有字符串中出现过的字符。如果某个字符在所有字符串中都出现过,则将其添加到最长公共前缀中。

  Args:
    strs: 字符串数组

  Returns:
    最长公共前缀
  """

  # 如果字符串数组为空,则返回空字符串
  if not strs:
    return ""

  # 找到字符串数组中最短的字符串的长度
  min_len = min(len(s) for s in strs)

  # 水平扫描字符串数组中的每个字符
  for i in range(min_len):
    # 记录所有字符串中出现过的字符
    chars = set()
    for s in strs:
      chars.add(s[i])

    # 如果所有字符串中出现过的字符只有一个,则将其添加到最长公共前缀中
    if len(chars) == 1:
      prefix += chars.pop()
    # 否则,返回最长公共前缀
    else:
      return prefix

  # 返回最长公共前缀
  return prefix

三、分治法:兵分两路,各取所长

分治法,顾名思义,就是将一个大问题分解成多个小问题,然后分别解决这些小问题,最后将这些小问题的解组合起来得到大问题的解。对于最长公共前缀,分治法就是将字符串数组分成两部分,分别求出两部分的最长公共前缀,然后将这两部分的最长公共前缀组合起来作为整个字符串数组的最长公共前缀。

def longestCommonPrefix_divide_and_conquer(strs):
  """
  分治法:将字符串数组分成两部分,分别求出两部分的最长公共前缀,然后将这两部分的最长公共前缀组合起来作为整个字符串数组的最长公共前缀。

  Args:
    strs: 字符串数组

  Returns:
    最长公共前缀
  """

  # 如果字符串数组为空,则返回空字符串
  if not strs:
    return ""

  # 如果字符串数组只有一个字符串,则返回这个字符串作为最长公共前缀
  if len(strs) == 1:
    return strs[0]

  # 将字符串数组分成两部分
  mid = len(strs) // 2
  left_strs = strs[:mid]
  right_strs = strs[mid:]

  # 分别求出两部分的最长公共前缀
  left_prefix = longestCommonPrefix_divide_and_conquer(left_strs)
  right_prefix = longestCommonPrefix_divide_and_conquer(right_strs)

  # 将这两部分的最长公共前缀组合起来作为整个字符串数组的最长公共前缀
  return find_common_prefix(left_prefix, right_prefix)

总结:从 LeetCode 14 迈向 LeetCode 高手之路

作为 LeetCode 的入门题目之一,最长公共前缀不仅考察了我们的算法思维和字符串处理能力,还为我们揭示了 LeetCode 题目的特点和解题方法。从暴力解法到高效解法,我们一步步深入理解了算法的设计和实现,也为我们进军 LeetCode 高手之路打下了坚实的基础。