部门有个同事,被架空了。 领导不给他派活,开会不叫他,邮件不抄送他
被架空这事,真不是电视剧专属,办公室里玩起来更阴。
一个同事,活不给,会不开,邮件也不带他。人是按时来公司了,工位也坐着,电脑也亮着,但整个部门像统一开了“屏蔽模式”,硬是把他活成了个背景板。表面没骂你,没辞退你,连冲突都不给,主打一个耗着你,耗到你自己先破防。
这比直接开还狠,因为你连申诉点都不好找。这就是职场版冷暴力,看着没动手,刀子全是软的。
我看这种操作,领导心里门儿清。真想留你,不可能两个月一点事都不给。说白了,就是不想担责任,又想让你自己体面消失。HR看见这种流程,估计都装没看见。
最惨的还不是走人,是你明知道自己被针对,还得每天打卡坐那儿,假装一切正常。那种班,真不是去上班,是去参加自己的离职倒计时
面试题:分隔链表
一看到“分隔链表”这题,很多人第一反应是新建数组、收集节点、再重连。能做,但链表题这么写,总有点绕。
这题其实没那么玄乎,难点不在算法复杂度,在指针别拧巴。尤其是你一边遍历,一边改 next,很容易把后面的链断掉。链表题我一般先盯住两件事:当前节点会不会丢,最后拼接会不会成环。别的都往后放。
题目的意思很直接:给你一个链表和一个值 x,把小于 x 的节点放前面,大于等于 x 的放后面,而且要保持原来的相对顺序。
注意,是“分隔”,不是“排序”。
比如:
1 -> 4 -> 3 -> 2 -> 5 -> 2, x = 3
处理完以后应该是:
1 -> 2 -> 2 -> 4 -> 3 -> 5
这里最稳的做法,不是原地硬调,而是准备两条链:
一条专门挂 < x 的节点。
一条专门挂 >= x 的节点。
最后再把两条链接起来。
这种写法很像线上拆流量。命中的进一个队列,没命中的进另一个队列,最后统一汇总。思路不花,代码也干净。
直接看实现:
publicclassSolution{
staticclassListNode{
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
public ListNode partition(ListNode head, int x){
ListNode smallDummy = new ListNode(-1);
ListNode bigDummy = new ListNode(-1);
ListNode smallTail = smallDummy;
ListNode bigTail = bigDummy;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next; // 先存,别把链搞丢
curr.next = null; // 断开当前节点,避免后面串出环
if (curr.val < x) {
smallTail.next = curr;
smallTail = curr;
} else {
bigTail.next = curr;
bigTail = curr;
}
curr = next;
}
smallTail.next = bigDummy.next;
return smallDummy.next;
}
}
这段代码里,真正值钱的不是双链表,而是这两句:
ListNode next = curr.next;
curr.next = null;
很多人写挂就挂在这。你要是不先把 next 存下来,当前节点一挪,后面的链就找不回来了。你要是不把 curr.next 断开,最后拼接时很可能把旧链关系也带过去,轻则结果乱,重则直接成环,while 一跑没头。
再说下为什么这题不建议上来就原地交换。
原地交换当然也能做,但你会发现链表不像数组,没有下标,找前驱节点、改指针方向、维护相对顺序,全是细活。面试里这种题,写得花不代表写得好。能稳稳过样例、边界也不炸,比什么都强。
边界情况也顺手过一遍:
空链表,直接返回 null。
所有节点都小于 x,那后半段链表为空。
所有节点都大于等于 x,那前半段链表为空。
链表里有重复值,也不用特殊处理,按顺序挂过去就行。
时间复杂度是 O(n),空间复杂度如果只算额外指针,就是 O(1)。别一看用了两个虚拟头节点就觉得空间变大了,这点对象开销在这题里根本不算事。
链表题说到底就一句话:节点可以换队,顺序别乱,尾巴别丢。