全员降薪 20%共渡难关,大家纷纷摸鱼,工作效率下降不止 20%,老板急了要求写日报,要精确要每半个小时干了什么。。
昨天群里一个朋友发了个帖,标题就一句话:“全员降薪20%,老板说要共渡难关。”下面的评论区,直接炸了。
然后更离谱的来了,老板发现大家开始摆烂了,急了!直接下命令:从明天开始写日报,每半小时记录一次干了啥。
我真是……笑死。你说你都不信任我了,我干嘛还替你卖命啊?而且日报写得比代码还勤快。。
咱就是说,工资减了是实打实的,效率掉了是肉眼可见的,现在还得自证清白?这性价比也太低了吧
职场嘛,说白了就是个等价交换。你减了我20%的钱,那我自然也得减点输出,不然我图啥?情绪价值吗?整不会……【备注:文末可领最新资料】
面试题:向下取整数对和
这个题目看起来好像没啥难度?“向下取整数对和”,光听名字可能一时间有点懵,但其实一上手你就会发现它是那种“上来一看,没啥意思;一深挖,嘿,还挺有意思”的题。
问题其实非常简单粗暴:给定一个整数数组 nums,问你有多少对下标 (i, j),满足 i < j 且 ⌊(nums[i] + nums[j])/2⌋ 恰好出现在 nums 中。
说实话,我第一反应是:这不就暴力枚举吗?两层 for 循环搞起,每一对 i, j 算一下和的平均数,再向下取整,然后看看这个数存不存在 nums 里,不就完事了么?
代码差不多是下面这个样子:
from math import floor
defcount_integer_average_pairs(nums):
count = 0
num_set = set(nums)
n = len(nums)
for i in range(n):
for j in range(i + 1, n):
avg = floor((nums[i] + nums[j]) / 2)
if avg in num_set:
count += 1
return count
这个思路吧,说不上高明,但胜在“真诚”😂。时间复杂度 O(n^2),看似不优雅,但对数据规模不大时它就是个解法。
但如果你问我,这能不能优化?当然能。咱们可以试试换个思路:别每次算完平均数再去 set 查是否存在,我们反过来,枚举数组中所有存在的数,然后去找有多少对 (i, j) 让他们的 average 恰好等于这个数。
而且注意 average 是向下取整的,这意味着 (nums[i] + nums[j]) // 2 == t,就等价于 nums[i] + nums[j] == 2 * t。
那我们可以怎么搞?枚举数组中每个 t,然后对于所有满足 nums[i] + nums[j] == 2 * t 的组合数做个计数。
那就需要一个 hash 表记录每个数字出现的次数,这样查找某个 x 是否存在、它的个数是多少,全是 O(1) 的。
下面是优化思路的代码实现:
from collections import Counter
defoptimized_count_integer_average_pairs(nums):
count = 0
freq = Counter(nums)
unique_vals = list(freq.keys())
for t in freq:
target = 2 * t
seen = set()
for x in unique_vals:
y = target - x
if y in freq and y notin seen:
if x == y:
count += freq[x] * (freq[x] - 1) // 2
else:
count += freq[x] * freq[y] // 2# 除以 2 是因为我们 x+y 和 y+x 是重复的
seen.add(x)
seen.add(y)
return count
我跟你讲这个优化后能顶不止一倍的效率提升。在你数组元素数量比较大、数据离散度又不高的时候,性能飞升。但说实话吧,代码看起来稍微没那么直观,不太好面试时候讲得清楚 😂。
说一个我踩的坑:有一次我忘了 x == y 的时候组合数应该是 C(n, 2),结果本来应该统计 3 对,硬是变成 6,对数翻倍了还看不出来,调试半天发现逻辑对但结果错了。哭笑不得...
再讲讲一个变体题,有人可能会问,那如果要求的是 (nums[i] + nums[j]) / 2 恰好等于 nums[k] 呢?这跟原题区别就大了,因为那就需要三重枚举或者先排序+双指针,场景完全不一样。
另外值得注意的是,如果你看到题目要求是向下取整,那就一定要小心负数的处理。Python 的 // 是向下取整不是截断除法,所以负数情况下 (a + b) // 2 是往下靠的,而不是简单把小数部分抛掉,比如 (-1 + -1) // 2 = -1 而不是 0。
当然你用 math.floor((a + b)/2) 也行,但那是浮点计算,可能会引入浮点误差,不推荐。
这题其实还挺适合拿来练手的,既可以考你暴力枚举的思维清晰度,也可以看看你是否能举一反三,进一步想到 hash 优化,甚至是桶计数(当数据范围受限时)。
好了,写到这我突然想起个段子:“程序员分三种,能写出正确代码的,能写出高效代码的,以及能讲清楚自己写的代码的。” 你是哪一种?😏
最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。总量高达650GB,全部免费领取