程序员老鬼

部门有个同事,被架空了。 领导不给他派活,开会不叫他,邮件不抄送他

被架空这事,真不是电视剧专属,办公室里玩起来更阴。

一个同事,活不给,会不开,邮件也不带他。人是按时来公司了,工位也坐着,电脑也亮着,但整个部门像统一开了“屏蔽模式”,硬是把他活成了个背景板。表面没骂你,没辞退你,连冲突都不给,主打一个耗着你,耗到你自己先破防。

Image

这比直接开还狠,因为你连申诉点都不好找。这就是职场版冷暴力,看着没动手,刀子全是软的。

我看这种操作,领导心里门儿清。真想留你,不可能两个月一点事都不给。说白了,就是不想担责任,又想让你自己体面消失。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)。别一看用了两个虚拟头节点就觉得空间变大了,这点对象开销在这题里根本不算事。

链表题说到底就一句话:节点可以换队,顺序别乱,尾巴别丢。