刚升小组长,下属比我年纪还大,怎么管?上个月刚被提成小组长,手下3个人,两个比我大3岁,一个还是老员工。
刚看到个贴子,说一网友刚升小组长,下面三个人俩比他大,还有一个老员工。安排任务老感觉对方不太当回事,开会也不说话,就纠结要不要请客吃饭,还是直接立规矩。
我觉得这事吧,先别纠结“我比他们小”,职场看的是角色和价值,不是辈分。有篇文章就说过,职场第一准则是价值,而不是努力。你现在的“价值”,就是把活儿带好,让大家跟着你把结果做出来。
我比较认同“先把事说明白,再谈感情”。先开个小范围会议,把目标、分工、决策方式讲清楚,让大家知道你是来解决问题的,不是来当哥们的。之后再一对一聊聊,听听老员工的想法,给足尊重。饭可以吃,但别指望一顿饭解决管理问题。
面试题:匹配子序列的单词数
昨天晚上快十一点,我在公司楼下等外卖,手机一刷,群里一个实习生跟我说:“哥,四数之和这道题我写了一下午,还是一团浆糊,你有空讲讲不?”我一看,这不就是经典面试题嘛,用 Java 写也不难,就是容易写成一坨 n⁴ 的屎山代码。
我先把题目翻成人话啊:给你一个 int 数组 nums,再给一个目标值 target,让你找出所有“四个数的组合”,这四个数加起来正好等于 target,而且组合不能重复,比如 [-2,-1,1,2] 和 [-1,-2,1,2] 算一个。
很多人第一反应是四层 for 循环,把所有四元组都枚举一遍,时间复杂度 O(n⁴),数组长一点就寄了。
正常一点的玩法是这样的:
先排序:
Arrays.sort(nums)排完序之后,有个好处是——去重就好搞了,双指针也能用上。外面两层 for 固定前两个数 i、j
第一层 i 从 0 到 n-4 第二层 j 从 i+1 到 n-3
里面一对双指针算“剩下两数之和”
左指针 l = j + 1,右指针r = n - 1当前和 sum = nums[i] + nums[j] + nums[l] + nums[r]如果 sum == target,记录一组sum < target,说明太小,l++sum > target,说明太大,r--
去重很关键,不然结果一堆重复
while(l < r && nums[l] == nums[l+1]) l++;while(l < r && nums[r] == nums[r-1]) r--;然后再 l++,r--开始下一轮
i 这一层:
if(i > 0 && nums[i] == nums[i-1]) continue;j 这一层:
if(j > i+1 && nums[j] == nums[j-1]) continue;找到一组解之后:
核心就是:外面两层枚举 + 里面两数之和,整体复杂度 O(n³),这在面试题里是完全能接受的。
直接给你一份能跑的写法,注意几个小细节我都写在注释里了:
import java.util.*;
publicclassFourSumSolution{
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>();
if (nums == null || nums.length < 4) {
return res;
}
Arrays.sort(nums);
int n = nums.length;
for (int i = 0; i < n - 3; i++) {
// 第一层去重
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j < n - 2; j++) {
// 第二层去重
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
int left = j + 1;
int right = n - 1;
while (left < right) {
// 防止溢出,先转成 long
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
if (sum == target) {
res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
// 左右指针去重
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
left++;
right--;
} elseif (sum < target) {
left++;
} else {
right--;
}
}
}
}
return res;
}
}
你自己写的时候,最容易翻车的三个点,我顺嘴提醒一下:
忘记排序:不排序去重会非常难受,还不好用双指针。 去重条件写错:特别是 j > i + 1这个地方,少写个加一,就会漏掉首个合法组合或者多算。int 溢出:数据范围一大, nums[i] + nums[j] + ...直接炸,所以我用的是long sum。
比如最经典的这个:
nums = [1, 0, -1, 0, -2, 2], target = 0
排序之后是 [-2, -1, 0, 0, 1, 2],你心里就有数了,答案应该是:
[-2, -1, 1, 2] [-2, 0, 0, 2] [-1, 0, 0, 1]
代码跑出来也会是这三个,顺序可能不一样,但没关系,面试官一般不管顺序。
复杂度简单说一下: 外面两层 for 是 O(n²),里面双指针一圈是 O(n),所以总的就是 O(n³)。空间上只用了结果列表,算 O(1) 额外空间。
差不多就这样,你可以先照着敲一遍,自己打几个用例跑一跑,熟悉一下指针的移动节奏。下次有人问你“四数之和”,你就可以像装模作样地说一句:“这个题啊,很经典的排序加双指针变形题”。我这边先去冲杯咖啡,等会还得改需求😅。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html