Python技术迷

清华硕士天塌了,根本找不到合适的工作,民企卷的要死。国企完全没信息。

刚看到个贴子,说清华硕士想进自动驾驶,面试聊得很开心,结果一个月后还是挂了。民企卷到飞起,国企又一点消息都没有,搞得人心态崩了 。

Image

我觉得这事吧,其实挺普遍的。学历再亮眼,也难敌大环境的竞争。网友们吐槽“刷了那么多Leetcode,真上战场也没啥用”,这话虽丧,但也点出了现实:面试更看重的是综合适配度,而不只是刷题数。

换个角度想,企业卷是因为行业不景气,大家都想招“最合适”的人。清华硕士找不到合适岗位,普通人更是难上加难。但这也提醒我们,别光死磕题库,得想办法把自己的项目经验和行业落地能力亮出来,才能在一堆简历里脱颖而出。

天不会塌,路也不会断。只是节奏没那么快,别急,厚积薄发才是正解 。【备注:文末可领最新资料】

面试题:最小总操作数

昨天晚上十一点多,在公司楼下吹风,手机里有人问“把数组里的数改成一样,最少要改几步?”我困得眼花但这题我熟,思路不绕:每次对任意元素 +1 或 -1,求把它们改成同一个值的最小总步数。答案其实指向一个词——中位数。

为什么是中位数

直觉版说法:你把大家都往某个目标值挪,每挪一步就是距离扣一。总成本就是所有元素到目标值的“绝对距离之和”。在数轴上,这种 L1 距离在单峰(凸)形状里,谷底就在中位数那里。 再细一点:如果目标值往右挪一格,左边的人更远了,右边的人更近了。只要左边人数 ≥ 右边人数,继续往右并不会更好,于是停在让两边“人数尽量平衡”的点——这正是中位数的定义。 长度为偶数时,中位区间里的任意点都行(两个中位数之间),成本相同。

算法小结

1)先把数组排序,取中位数 m。 2)答案是 ∑|a_i - m|。 时间复杂度 O(n log n),空间 O(1)(就地排序)。如果你追求更快,可以用“线性时间选第 k 小”(quickselect)找中位数,把整体降到期望 O(n)。

from typing import List

defmin_moves_to_equal(nums: List[int]) -> int:
ifnot nums:  # 空数组,0 步
return0
    arr = sorted(nums)
    n = len(arr)
    median = arr[n // 2]  # 偶数长度取右中位,等价
return sum(abs(x - median) for x in arr)

# 小测一下
print(min_moves_to_equal([1, 10, 2, 9]))   # 16
print(min_moves_to_equal([1, 2, 3]))       # 2
print(min_moves_to_equal([5, 5, 5]))       # 0

你可能会问,偶数长度是不是该取两个中位数的平均?别,被平均后可能不是整数,且即便取整,也不保证最好。正确做法是取任意一个中位数;如果你想“证实”它们一样好,可以都算一遍看成本相同。

线性时间的选择(进阶可选)

import random

defkth_element(nums, k):
# 返回第 k 小(0-based)。期望 O(n)
    l, r = 0, len(nums) - 1
whileTrue:
if l == r:
return nums[l]
        pivot = nums[random.randint(l, r)]
        i, j, t = l, r, l
# 三路划分
while t <= j:
if nums[t] < pivot:
                nums[i], nums[t] = nums[t], nums[i]
                i += 1; t += 1
elif nums[t] > pivot:
                nums[t], nums[j] = nums[j], nums[t]
                j -= 1
else:
                t += 1
if k < i:
            r = i - 1
elif k > j:
            l = j + 1
else:
return pivot

defmin_moves_linear(nums: List[int]) -> int:
ifnot nums:
return0
    arr = nums[:]  # 不污染输入
    n = len(arr)
    median = kth_element(arr, n // 2)
return sum(abs(x - median) for x in nums)

这版不排序,通过三路划分找中位数,适合特别长的数组或对性能较敏感的服务端批处理。

常见变体与坑

  • 负数、重复值? 都没事,绝对值处理一把梭。
  • 溢出风险? Python 的 int 不会溢出,但别语言要留心。
  • 目标必须是数组里的数吗? 不必须,只要是中位区间内(偶数长度)或中位点(奇数),不一定出现在原数组里。
  • 权重版:如果每个数有权重 w_i,最优是加权中位数(累计权到达总权一半的位置)。
defmin_moves_weighted(values: List[int], weights: List[int]) -> int:
    pairs = sorted(zip(values, weights))
    total = sum(weights)
    half = (total + 1) // 2
    acc = 0
    median = pairs[-1][0]
for v, w in pairs:
        acc += w
if acc >= half:
            median = v
break
return sum(abs(v - median) * w for v, w in pairs)

差不多就这样。这个题的“灵魂”就是:L1 距离→中位数,记住这条,换皮多少次都不怕。行了我去热杯咖啡,眼皮打架了。

-END-

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

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领