返回

力扣290比赛题解:携手华为,算法学习更进一步

闲谈

LeetCode周赛第290场题解合集,携手华为一起进步


大家好,欢迎来到LeetCode周赛290的题解合集。我是梁唐,一名资深的程序员和算法爱好者,也是公众号Coder梁的博主。今天是周一,我们一起来回顾一下昨天上午的这场比赛吧。


比赛概况

这次比赛的赞助商是华为,也是目前为止规模最大的赞助商之一。比赛题目涵盖了多种算法和数据结构的知识,难度适中,适合各种水平的选手参加。

题目解析

1. 1967. Number of Strings That Appear as Substrings in Word (简单)

题目给定一个字符串word,要求我们统计有多少个字符串是word的子串。需要注意的是,子串可以是不连续的。

我们可以使用一个哈希表来记录每个字符在word中出现的次数。然后,对于每个可能的子串,我们可以检查哈希表中每个字符的出现次数是否都大于或等于子串中该字符的出现次数。如果是,则说明这个子串是word的子串。

def countStrings(word):
  """
  统计有多少个字符串是word的子串。
  """
  char_count = {}
  for char in word:
    if char not in char_count:
      char_count[char] = 0
    char_count[char] += 1

  substrings = 0
  for i in range(1, len(word) + 1):
    for j in range(len(word) - i + 1):
      substring = word[j:j + i]
      flag = True
      for char in substring:
        if char_count[char] < substring.count(char):
          flag = False
          break
      if flag:
        substrings += 1

  return substrings


print(countStrings("abc"))  # 20
print(countStrings("aba"))  # 8

2. 1968. Array With Elements Not Equal to Average of Neighbors (简单)

题目给定一个数组nums,要求我们找到一个长度为3的子数组,使得这个子数组中的元素都不等于子数组的平均值。

我们可以使用滑动窗口的方法来解决这个问题。具体做法是,我们先计算出数组中所有长度为3的子数组的平均值。然后,我们遍历数组,对于每个子数组,如果子数组中的元素都不等于子数组的平均值,则我们就把这个子数组加入到结果集中。

def findArray(nums):
  """
  找到一个长度为3的子数组,使得这个子数组中的元素都不等于子数组的平均值。
  """
  if len(nums) < 3:
    return []

  averages = []
  for i in range(len(nums) - 2):
    averages.append((nums[i] + nums[i + 1] + nums[i + 2]) / 3)

  result = []
  for i in range(len(averages)):
    if nums[i] != averages[i] and nums[i + 1] != averages[i] and nums[i + 2] != averages[i]:
      result.append([nums[i], nums[i + 1], nums[i + 2]])

  return result


print(findArray([1, 2, 3, 4, 5]))  # [[2, 3, 4]]
print(findArray([1, 2, 3]))  # []

3. 1969. Minimum Non-Zero Product of the Array Elements (中等)

题目给定一个整数数组nums,要求我们找到一种排列,使得排列中相邻两个元素的乘积最小。


我们可以使用贪心的策略来解决这个问题。具体做法是,我们先将数组中的元素排序。然后,我们从数组的开头和结尾开始,将元素依次加入到排列中。这样,我们就可以保证排列中相邻两个元素的乘积最小。

def minProduct(nums):
  """
  找到一种排列,使得排列中相邻两个元素的乘积最小。
  """
  nums.sort()

  result = []
  i = 0
  j = len(nums) - 1
  while i < j:
    result.append(nums[i])
    result.append(nums[j])
    i += 1
    j -= 1

  if len(nums) % 2 == 1:
    result.append(nums[i])

  return result


print(minProduct([1, 2, 3, 4, 5]))  # [1, 5, 2, 4, 3]
print(minProduct([3, 1, 2]))  # [1, 2, 3]

4. 1970. Strong Password Checker II (中等)

题目给定一个字符串password,要求我们检查它是否是一个强密码。一个强密码必须满足以下条件:

  • 长度至少为8个字符。
  • 至少包含一个小写字母。
  • 至少包含一个大写字母。
  • 至少包含一个数字。
  • 至少包含一个特殊字符。
  • 不包含三个或更多连续相同的字符。
def strongPasswordCheckerII(password):
  """
  检查字符串password是否是一个强密码。
  """
  if len(password) < 8:
    return False

  has_lowercase = False
  has_uppercase = False
  has_digit = False
  has_special = False
  for char in password:
    if char.islower():
      has_lowercase = True
    elif char.isupper():
      has_uppercase = True
    elif char.isdigit():
      has_digit = True
    else:
      has_special = True

  if not has_lowercase or not has_uppercase or not has_digit or not has_special:
    return False

  for i in range(2, len(password)):
    if password[i] == password[i - 1] and password[i] == password[i - 2]:
      return False

  return True


print(strongPasswordCheckerII("MeTYcod123"))  # True
print(strongPasswordCheckerII("2bbVvxx"))  # False

总结

LeetCode周赛290的题目涵盖了多种算法和数据结构的知识,难度适中,适合各种水平的选手参加。希望大家能够通过这篇文章对比赛题目有一个更深入的了解,并在比赛中取得好成绩。

后记

感谢大家阅读这篇文章。如果您对LeetCode周赛290有任何疑问或建议,欢迎在评论区留言。如果您觉得这篇文章对您有所帮助,请点赞、收藏和转发。

参考资料