Python技术迷

马上年底了,被裁员被退婚,也是被我摊上了~

刚看到个贴子,说女生年底被裁,又赶上被退婚,整个人都有点“怎么坏事都轮到我”的无语感。

Image

这事吧和裁员其实没啥关系,重点还是那段感情。

网友们的回复我也看了,有说男方现实的,也有说女生太独立的。

但从我的角度看,婚前买房是很正常的安全感需求,就像出门带伞一样,谁也不能要求你永远赌晴天。可男方把这事上纲上线到“你不一心一意”,这就有点小题大做了。

而她真正焦虑的,其实是马上30岁的压力——继续催婚、继续相亲,永无止境。怎么说呢,催归催,生活还是自己的。感情不是任务清单,遇错了人,早点结束比硬撑强太多。

走到这一步也别太丧,每一次重来都是把人生盘重新洗一遍。【备注:文末可领最新资料】

面试题:三个数的最大乘积

给你一堆整数,正的负的乱七八糟,从里面随便挑 3 个数 相乘,问能得到的 最大乘积 是多少,用 Python 写个算法来算。

如果题目只说“最大三个数的和/乘积”,很多人第一反应都是:

那不就把数组排个序,取最大的三个吗?

但这里有个坑:有负数。

举个特别典型的例子:

nums = [-10, -9, 1, 2, 3]

如果你只取最大的三个数: 3 * 2 * 1 = 6

但如果你取: (-10) * (-9) * 3 = 270

负负得正,一下就大多了,所以我们其实要考虑两种可能:

  1. 最大的三个正数相乘
  2. 最小的两个负数 * 最大的一个正数

答案就是这两种里面取更大的那个。

先从好理解的版本来,思路非常简单:

  1. 把数组整体排个序(从小到大)

  2. 取出:

  • 最后三个数:a[-1], a[-2], a[-3]
  • 最前两个数:a[0], a[1](可能是最小的两个负数)
  • 计算:

    • p1 = a[-1] * a[-2] * a[-3]
    • p2 = a[0] * a[1] * a[-1]
  • 返回 max(p1, p2)

  • 代码直接上:

    from typing import List

    defmax_product_of_three_sort(nums: List[int]) -> int:
    if len(nums) < 3:
    raise ValueError("数组里至少要有三个数")

        nums.sort()
        n = len(nums)

    # 情况一:最大的三个数相乘
        p1 = nums[n - 1] * nums[n - 2] * nums[n - 3]
    # 情况二:最小的两个数(可能是负数) * 最大的一个数
        p2 = nums[0] * nums[1] * nums[n - 1]

    return max(p1, p2)

    这个版本的时间复杂度是 O(n log n),一般面试也能过,但如果面试官继续问:“能不能 O(n) 一次遍历搞定?”我们就得换个写法了。

    其实要算上面那两个乘积,本质上只需要知道这 5 个数:

    • 最大的三个数:max1 ≥ max2 ≥ max3
    • 最小的两个数(最小的、第二小的):min1 ≤ min2

    那我们可以一边遍历数组,一边维护这 5 个变量:

    • 当前数比 max1 大,就把 max1、max2、max3 往后挪一下
    • 同理更新 max2、max3
    • 对于 min1、min2 也是类似逻辑

    遍历完之后:

    • 最大三个数乘积:max1 * max2 * max3
    • 最小两个数 * 最大数:min1 * min2 * max1

    代码长得像这样:

    from typing import List
    import math

    defmax_product_of_three(nums: List[int]) -> int:
    if len(nums) < 3:
    raise ValueError("数组里至少要有三个数")

    # 初始化,max 用 -inf,min 用 +inf
        max1 = max2 = max3 = -math.inf
        min1 = min2 = math.inf

    for x in nums:
    # 更新最大三数
    if x > max1:
                max3 = max2
                max2 = max1
                max1 = x
    elif x > max2:
                max3 = max2
                max2 = x
    elif x > max3:
                max3 = x

    # 更新最小两数
    if x < min1:
                min2 = min1
                min1 = x
    elif x < min2:
                min2 = x

        p1 = max1 * max2 * max3
        p2 = min1 * min2 * max1
    return max(p1, p2)

    这个版本的时间复杂度是 O(n),空间 O(1),面试官一般会挺满意。

    你写完之后,自己心里也要有点数,看下这几种:

    1. 全是正数例如 [1, 2, 3, 4]那其实就等价于最大三个数相乘:4 * 3 * 2

    2. 有正有负例如 [-10, -9, 1, 2, 3]答案来自:(-10) * (-9) * 3

    3. 全是负数例如 [-5, -4, -3, -2]最大乘积其实是“绝对值最大的三个”,也就是:(-2) * (-3) * (-4) = -24这套逻辑用上面的算法也能自动跑出来,不用特判。

    4. 有零的情况如果有很多负数,又有 0,比如 [-5, -4, 0, 1]算法照样成立,因为该乘负就乘负,该乘零也会反映在 max1/max2/min1 等变量里。

    你可以随便写几组数据测测:

    if __name__ == "__main__":
        tests = [
            [1, 2, 3, 4],            # 4*3*2=24
            [-10, -9, 1, 2, 3],      # -10*-9*3=270
            [-5, -4, -3, -2],        # -2*-3*-4=-24
            [-10, -9, -8, 1],        # 1*-8*-9=72
            [-10, -9, 0, 1, 2],      # -10*-9*2=180
        ]
    for arr in tests:
            print(arr, "=>", max_product_of_three(arr))

    跑一遍结果对得上,基本这个题就稳了。

    -END-

    我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

    🔥虎哥私藏精品🔥

    虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB