女朋友失业半年了,前两天去ktv应聘服务员了,一天底薪800,有时候表现好5k多,但是我觉得她不爱我了,回来抱抱都不给了
女朋友失业半年,去KTV应聘服务员,说一天保底800,状态好还能拿几千。你在那琢磨“她是不是不爱我了”,回来不让抱了,感情淡了。
不是,重点是这个吗?
正常服务员什么行情,大家心里都有数。一天800还只是底薪,表现好直接上五千多,这活儿要真这么轻松,打工人早把门槛踩烂了。你还搁那分析感情问题,网友都替你着急。
当然了,也不能上来就给人扣帽子。可能她就是压力大,工作环境累,回来不想说话不想亲近,这也有可能。但你俩现在最大的问题,不是抱不抱,而是她到底在做什么、合同怎么签、钱从哪来、有没有风险。
感情里装傻可以一两天,不能一直装。该问就问清楚,别最后全网都看懂了,就你还在原地心疼。
四层 for 一写上去,这题就已经有点危险了。
统计特殊四元组 这个题,条件不绕:
nums[a] + nums[b] + nums[c] == nums[d]
并且下标必须满足:
a < b < c < d
第一眼很容易写成这样:枚举 a、b、c、d,碰到相等就加一。能过一些小数据,但这代码我一般不太愿意留。不是因为它错,而是它没有利用下标顺序,后面稍微换个数据范围就容易被卡。
这里我会把式子拆一下:
nums[a] + nums[b] = nums[d] - nums[c]
这样就清楚了。
当我们枚举 c 和 d 的时候,只要知道在 c 左边有多少组 (a, b) 满足某个和,就能直接把答案加上去。
也就是说,不要每次都回头重新扫 a、b。提前把左边两数之和存起来。
看代码:
import java.util.HashMap;
import java.util.Map;
classSolution{
publicintcountQuadruplets(int[] nums){
int n = nums.length;
int ans = 0;
Map<Integer, Integer> pairSumCount = new HashMap<>();
for (int c = 2; c < n - 1; c++) {
int b = c - 1;
for (int a = 0; a < b; a++) {
int sum = nums[a] + nums[b];
pairSumCount.put(sum, pairSumCount.getOrDefault(sum, 0) + 1);
}
for (int d = c + 1; d < n; d++) {
int need = nums[d] - nums[c];
ans += pairSumCount.getOrDefault(need, 0);
}
}
return ans;
}
}
这段代码里最容易看错的是 pairSumCount 更新的位置。
它不是一上来就把所有 (a,b) 都塞进去。
因为题目要求:
a < b < c < d
所以当 c 固定时,合法的 b 最大只能是 c - 1。
每次 c 往右走一步,我们只补上新出现的这批 pair:
b = c - 1
a = 0 ... b - 1
这样 pairSumCount 里面永远只存 c 左边的两数和,不会混进非法下标。
举个小例子:
nums = [1, 2, 3, 6]
当 c = 2 时,左边只有 (0,1):
nums[0] + nums[1] = 3
右边 d = 3:
nums[3] - nums[2] = 6 - 3 = 3
刚好对上,答案加一。
这题麻烦的地方不在加法,而在下标顺序。很多四元组题看着像暴力枚举,其实都能从等式两边拆开。左边提前记账,右边查账。
四层循环是能写,但写完最好多看一眼:有没有重复算,有没有把已经确定的顺序信息浪费掉。这个题就是典型的,少想一步也能过,想多一步代码就顺了。