刚升小组长,下属比我年纪还大,怎么管?上个月刚被提成小组长,手下3个人,两个比我大3岁,一个还是老员工。
刚看到个贴子,说自己刚升小组长,带三个人,两个还比自己大,安排工作老感觉他们不太服,纠结是请吃饭还是先立规矩。
我觉得这事吧,关键真不是年龄,而是你能不能在“角色”上站稳。你是小组长,就代表公司给了你这块牌子,你要做的是:把目标、分工、标准讲清楚,而不是先急着当好人。
规矩一定要有,但别上来就端着,可以用“商量式立规矩”——开个小会,先说团队要完成什么,再一起定流程和要求,让他们参与进去,比你单方面宣布好用多了。
请吃饭也能有,但不要带着“求人你们多多关照”的心态,而是边吃边聊各自擅长啥、以前怎么做,更像一场信息交流。网友有的让他硬刚,有的让他猛示好,我比较认同的是:软硬结合,业务上有担当,态度上懂尊重。
算法题:四数之和
昨天晚上十一点多,在公司楼下啃着一盒还凉着的麻辣烫,我在那儿刷题,手机一抬头,看到个老熟人:四数之和。心里一想:哎哟,这不就是两数之和、三数之和全家桶最后一个嘛。
大概意思就是: 给你一个整数数组 nums,再给你一个目标值 target,让你从数组里挑四个数出来,四个数的和等于 target,而且结果里不能有重复的四元组。
比如:
nums = [1, 0, -1, 0, -2, 2]
target = 0
可能的答案里会有:
[-2, -1, 1, 2]
[-2, 0, 0, 2]
[-1, 0, 0, 1]
注意几点小坑:
四个数要按值算重复,比如 [-1,0,0,1]只算一组,位置不管四元组里面一般会按从小到大排一下,方便去重
我一开始想的也很“暴力”——四层 for 循环,硬找:
for i in range(n):
for j in range(i+1, n):
for k in range(j+1, n):
for h in range(k+1, n):
if nums[i] + nums[j] + nums[k] + nums[h] == target:
...
这个时间复杂度是啥水平呢? 四层循环,O(n^4),数组一大立马爆炸,面试官都能当场看你 CPU 冒烟。
所以这个写法,理解题还行,上线肯定不行。
老套路了,你们知道吧,三数之和怎么写,这个题就差不多,只是多了一层循环。
整体思路我用人话说下:
先排序,这样方便去重、也方便用双指针
第一层循环定第一个数
a = nums[i]第二层循环定第二个数
b = nums[j]剩下的两个数,就在区间
[j+1, n-1]里用 左右指针 去扫
left = j + 1right = n - 1当前四数之和: total = nums[i] + nums[j] + nums[left] + nums[right]
如果 total < target,说明要大一点,left += 1
如果 total > target,说明要小一点,right -= 1
如果刚好等于,收集一组,然后左右一起缩,并且跳过相同元素,防止重复
中间有几个非常重要的“去重动作”,不然结果里一堆重复四元组,看着都头大:
第一层循环:
if i > 0 and nums[i] == nums[i-1]: continue第二层循环:
if j > i+1 and nums[j] == nums[j-1]: continue找到一组解后:
left往右移动时跳过相同值right往左移动时也跳过相同值
别说了,代码给你整全一点,你可以直接拿去跑:
from typing import List
deffour_sum(nums: List[int], target: int) -> List[List[int]]:
# 先排序,方便双指针和去重
nums.sort()
n = len(nums)
res = []
for i in range(n):
# 第一个数去重,避免相同起点重复计算
if i > 0and nums[i] == nums[i - 1]:
continue
for j in range(i + 1, n):
# 第二个数去重,同样的道理
if j > i + 1and nums[j] == nums[j - 1]:
continue
# 现在我们要在 [j+1, n-1] 里找两个数
left = j + 1
right = n - 1
while left < right:
total = nums[i] + nums[j] + nums[left] + nums[right]
if total == target:
res.append([nums[i], nums[j], nums[left], nums[right]])
# 左右同时移动,并跳过相同的数,防止重复组合
left_val = nums[left]
right_val = nums[right]
while left < right and nums[left] == left_val:
left += 1
while left < right and nums[right] == right_val:
right -= 1
elif total < target:
# 和太小,left 往右走,让总和变大
left += 1
else:
# 和太大,right 往左走,让总和变小
right -= 1
return res
if __name__ == "__main__":
nums = [1, 0, -1, 0, -2, 2]
target = 0
print(four_sum(nums, target))
你可以自己随便换几组数据试一下,比如全是 0 的、带重复数字的、数组特别短的,顺便感受一下去重逻辑是不是生效了。
简单算下:
外面两层循环 i、j:大概O(n^2)里面一圈双指针,每次 while 至少移动一个指针:整段区间只会被扫一遍,所以是 O(n)乘在一起:**整体时间复杂度 O(n^3)**,空间复杂度主要是排序O(log n)的栈 + 结果集
理论上还可以加一点“剪枝”优化,比如:
如果 nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target,后面只会更大,可以直接 break如果 nums[i] + nums[n-1] + nums[n-2] + nums[n-3] < target,那 i 这个起点肯定不行,可以 continue
面试的时候,你嘴上提一句“可以再做个上下界剪枝”,加分的。
行啦,四数之和差不多就这点事,多写几遍你就会发现:题目换成三数、k 数,整体都是一套思路。 我先去给麻辣烫热一下,你有别的算法题也可以丢过来一起唠。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB