返回

LeetCode每日一题: 628. 三个数的最大乘积的突破口在哪里?

见解分享

好的,以下是关于LeetCode每日一题的专业技术文章:

引言

LeetCode每日一题是程序员们磨炼算法和编程能力的绝佳平台。628. 三个数的最大乘积是其中一道经典题目,考察了选手们对数组操作和贪心算法的掌握程度。本文将深入剖析这道题目的解题思路,提供清晰的实现步骤和代码示例,帮助读者轻松掌握解题技巧。

题目背景

给定一个整数数组nums,找到三个不同的整数a、b和c,使得a、b和c的乘积为数组nums中三个整数的最大乘积。

突破口

这道题目的关键在于寻找突破口,即找到一个快速且有效的方法来确定a、b和c的候选值。我们可以从以下两个方面入手:

  • 寻找最大值和最小值: 由于乘积为正数,因此a、b和c中至少有一个是正数,至少有一个是负数。因此,我们可以先找到数组nums中的最大值和最小值,作为a和c的候选值。
  • 考虑特殊情况: 如果数组nums中存在两个或多个负数,则a、b和c都可能为负数。此时,我们需要考虑特殊情况,即a、b和c都为负数时的情况。

实现步骤

根据上述突破口,我们可以将解题步骤分为以下几步:

  1. 找到数组nums中的最大值和最小值。
  2. 判断数组nums中是否存在两个或多个负数。
  3. 如果存在两个或多个负数,则计算数组nums中所有负数的乘积,作为a、b和c的候选值。
  4. 否则,选择最大值作为a的候选值,最小值作为c的候选值。
  5. 遍历数组nums,找到与a和c不同的最大值和最小值,作为b的候选值。
  6. 计算a、b和c的乘积,更新最大乘积。
  7. 重复步骤5和6,直到遍历完数组nums。

代码示例

def maxProduct(nums):
    # 寻找最大值和最小值
    max1, max2 = float('-inf'), float('-inf')
    min1, min2 = float('inf'), float('inf')

    for num in nums:
        if num > max1:
            max2 = max1
            max1 = num
        elif num > max2:
            max2 = num

        if num < min1:
            min2 = min1
            min1 = num
        elif num < min2:
            min2 = num

    # 判断是否存在两个或多个负数
    negative_count = 0
    for num in nums:
        if num < 0:
            negative_count += 1

    # 如果存在两个或多个负数
    if negative_count >= 2:
        return max(max1 * max2 * min1, min1 * min2 * max1)
    # 否则
    else:
        # 寻找与max1和min1不同的最大值和最小值
        max3, min3 = float('-inf'), float('inf')
        for num in nums:
            if num != max1 and num > max3:
                max3 = num
            if num != min1 and num < min3:
                min3 = num

        # 计算最大乘积
        return max(max1 * max2 * max3, max1 * min1 * min2)


# 测试
nums = [1, 2, 3, 4, 5]
result = maxProduct(nums)
print(result)  # 输出:120

复杂度分析

  • 时间复杂度:O(n),其中n为数组nums的长度。
  • 空间复杂度:O(1),因为我们只使用了有限的几个变量。

总结

通过本文的详细讲解,相信您已经掌握了LeetCode每日一题628: 三个数的最大乘积的解题思路和实现方法。如果您还有其他问题,欢迎随时提出。