今天看到一个让人看呆了的HR裁员黑套路,真的是让人大开眼界。
套路一是这样的:员工不签协议,HR就说和领导再争取一下,可是没多久你的门禁、电脑、账号全都被收回,最后以“矿工”为由开除你,一分钱补偿都没有。
套路二是公司签劳动合同时会写“公司有权单方面调岗”,HR解释成企业用工自主权,结果你被调到一个根本不擅长的岗位,逼你主动离职。最后,你不仅得不到赔偿,连个好词都没听到。
至于套路三,听说公司要搬到其他城市,你如果不能去就得自己辞职。结果一年过去了,公司根本没搬,补偿一分钱没有。这种套路简直是把员工当傻子看。
现在这种套路虽然少了,但还是要小心,以防万一。大家的建议是:先学习劳动法,遇到问题留证据,录音、拍照,确保自己不吃亏。而签合同时一定要仔细,防止出现霸王条款。
今日算法题
好了,看完套路,我们回归正题,今天我们来聊一聊一个挺有趣的链表题目——奇偶链表。对于程序员来说,链表的操作是一个很常见的面试题目,而奇偶链表又是链表中一个相对简单但又能锻炼逻辑思维的题目。
首先,我们简单回顾一下链表。链表其实是一种线性的数据结构,由一系列节点组成,每个节点都有两个部分:数据域和指向下一个节点的指针(或者说引用)。
如果你还没有弄懂链表是什么,可以想象成一列排队的人,每个人手里都拿着一个指向下一个人的纸条。
在这个问题中,我们给定的是一个单链表,任务是将链表重新排序,使得所有的奇数节点排在偶数节点之前,并保持奇偶节点原有的相对顺序。
具体来说,链表的奇数节点是指位置为1、3、5、7……的节点,偶数节点是指位置为2、4、6、8……的节点。
想象一下,如果你有一个链表:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8
,你的目标是把它转换为:1 -> 3 -> 5 -> 7 -> 2 -> 4 -> 6 -> 8
,也就是将所有奇数位置的节点提取到前面,偶数位置的节点排到后面,且保持相对顺序不变。
我们可以用非常简单的思路来解决这个问题。首先,我们可以创建两个指针,一个用于保存奇数位置的节点,另一个用于保存偶数位置的节点。然后,我们遍历整个链表,将奇数节点和偶数节点分别连接到两个不同的链表中。最后,我们只需要将奇数链表的尾部连接上偶数链表的头部就完成了。
代码实现起来也很直接。我们首先定义两个指针,一个指向奇数链表的头部,另一个指向偶数链表的头部。接着,我们遍历原链表,按照奇数、偶数顺序将节点分别加入到这两个链表中,最后将奇数链表和偶数链表拼接起来。
具体的代码如下:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def oddEvenList(head: ListNode) -> ListNode:
if not head or not head.next:
return head
odd = head # 奇数节点的链表
even = head.next # 偶数节点的链表
even_head = even # 保留偶数链表的头部,以便最后连接
# 从第三个节点开始,依次将奇数节点和偶数节点分开
while even and even.next:
odd.next = odd.next.next # 将奇数节点连接到下一个奇数节点
even.next = even.next.next # 将偶数节点连接到下一个偶数节点
odd = odd.next # 移动奇数指针
even = even.next # 移动偶数指针
# 将奇数链表的尾部连接到偶数链表的头部
odd.next = even_head
return head
让我们逐步解析一下这段代码。
首先,定义了一个 ListNode
类来表示链表的节点。每个节点有两个属性:val
表示节点的值,next
表示指向下一个节点的指针。接着,在 oddEvenList
函数中,我们首先处理了两个特殊情况:链表为空或者链表只有一个节点。对于这两种情况,直接返回原链表,因为它们不需要排序。
接下来,我们定义了两个指针:odd
和 even
。odd
用来指向奇数位置的节点,even
用来指向偶数位置的节点。由于我们需要保留偶数链表的头部,我们还定义了一个 even_head
来保存偶数链表的开始位置。
然后,我们进入一个 while
循环,直到偶数链表的尾部。每一次循环,我们都会将 odd
链表的下一个节点指向下一个奇数节点,将 even
链表的下一个节点指向下一个偶数节点。这样,就完成了奇偶链表的拆分。
最后,奇数链表的尾部需要指向偶数链表的头部,这样就把两个链表拼接在一起了。
时间复杂度方面,整个链表我们只遍历了一次,所以时间复杂度是 O(n),其中 n 是链表的长度。空间复杂度是 O(1),因为我们只使用了几个额外的指针来操作链表,不需要额外的空间。
简单总结一下,这道题的核心就是如何用两个指针将奇偶节点分开,并最终将它们连接在一起。思路清晰且高效,是一道非常经典的链表题目。如果你在面试中遇到类似的题目,可以尝试用这个方法进行解答。