返回

层层突破,算法炼金:LeetCode实战特训(五道高频算法题精讲)

后端

算法实战,开启冒险之旅

算法是计算机科学的基石,也是编程人员必备的技能。LeetCode作为全球知名的算法题库,收录了大量高频算法题,是算法学习和训练的绝佳平台。在这场算法冒险之旅中,我们将从五道高频算法题开始,逐步提升你的算法技能。

LeetCode小牛试刀五道题

1. 两数之和

两数之和是LeetCode最经典的问题之一,也是算法学习的入门题。给定一个整数数组nums和一个目标值target,找出数组中两个数的和等于target的索引。

def two_sum(nums, target):
  """
  :type nums: List[int]
  :type target: int
  :rtype: List[int]
  """
  # 创建一个字典,存储数字和索引的映射
  num_to_index = {}
  # 遍历数组
  for i, num in enumerate(nums):
    # 计算目标值与当前数字的差值
    complement = target - num
    # 如果差值在字典中,则说明找到了两数之和
    if complement in num_to_index:
      return [num_to_index[complement], i]
    # 否则,将当前数字和索引添加到字典中
    else:
      num_to_index[num] = i
  # 如果没有找到两数之和,则返回空列表
  return []

2. 无重复字符的最长子串

无重复字符的最长子串问题要求你找到一个字符串中不包含重复字符的最长子串。

def longest_substring_without_repeating_characters(s):
  """
  :type s: str
  :rtype: int
  """
  # 创建一个滑动窗口,存储当前子串
  window = set()
  # 创建两个指针,分别指向窗口的左端和右端
  left, right = 0, 0
  # 记录最长子串的长度
  max_length = 0
  # 遍历字符串
  while right < len(s):
    # 如果当前字符不在滑动窗口中,则将其添加到滑动窗口中
    if s[right] not in window:
      window.add(s[right])
      # 更新最长子串的长度
      max_length = max(max_length, right - left + 1)
      # 右指针右移
      right += 1
    # 否则,将左指针右移,并从滑动窗口中删除左指针指向的字符
    else:
      window.remove(s[left])
      left += 1
  # 返回最长子串的长度
  return max_length

3. 最长回文子串

最长回文子串问题要求你找到一个字符串中最长的回文子串。

def longest_palindromic_substring(s):
  """
  :type s: str
  :rtype: str
  """
  # 创建一个二维数组,存储子串是否是回文的标志
  dp = [[False] * len(s) for _ in range(len(s))]
  # 初始化对角线上的元素为True
  for i in range(len(s)):
    dp[i][i] = True
  # 记录最长回文子串的长度和起始索引
  max_length, start = 1, 0
  # 遍历字符串
  for i in range(len(s) - 1, -1, -1):
    for j in range(i + 1, len(s)):
      # 如果子串的长度为2,则直接判断两个字符是否相等
      if j - i == 1:
        dp[i][j] = s[i] == s[j]
      # 否则,判断子串的左右两端是否相等,以及子串的中间部分是否是回文子串
      else:
        dp[i][j] = s[i] == s[j] and dp[i + 1][j - 1]
      # 更新最长回文子串的长度和起始索引
      if dp[i][j] and j - i + 1 > max_length:
        max_length = j - i + 1
        start = i
  # 返回最长回文子串
  return s[start:start + max_length]

4. 寻找两个有序数组的中位数

寻找两个有序数组的中位数问题要求你找到两个有序数组的中位数。

def find_median_sorted_arrays(nums1, nums2):
  """
  :type nums1: List[int]
  :type nums2: List[int]
  :rtype: float
  """
  # 将两个数组合并为一个有序数组
  merged_nums = sorted(nums1 + nums2)
  # 如果合并后的数组的长度是偶数,则中位数是两个中间数的平均值
  if len(merged_nums) % 2 == 0:
    median = (merged_nums[len(merged_nums) // 2] + merged_nums[len(merged_nums) // 2 - 1]) / 2
  # 否则,中位数是中间数
  else:
    median = merged_nums[len(merged_nums) // 2]
  # 返回中位数
  return median

5. 最长公共子序列

最长公共子序列问题要求你找到两个字符串的最长公共子序列。

def longest_common_subsequence(text1, text2):
  """
  :type text1: str
  :type text2: str
  :rtype: int
  """
  # 创建一个二维数组,存储子序列的长度
  dp = [[0] * (len(text2) + 1) for _ in range(len(text1) + 1)]
  # 遍历字符串
  for i in range(1, len(text1) + 1):
    for j in range(1, len(text2) + 1):
      # 如果两个字符相等,则子序列的长度为上一个子序列的长度加1
      if text1[i - 1] == text2[j - 1]:
        dp[i][j] = dp[i - 1][j - 1] + 1
      # 否则,子序列的长度为上一个子序列的长度的最大值
      else:
        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
  # 返回最长公共子序列的长度
  return dp[len(text1)][len(text2)]