Day82 | 灵神 | 快慢指针 重排链表
143.重排链表
思路:
笔者直接给跪了,这个难度真是mid吗
直接去看灵神的视频
环形链表II【基础算法精讲 07】_哔哩哔哩_bilibili
1.简单来说就是,找到链表的中间节点,然后翻转后半部分链表,然后一次修改指针就好
2.其实自己做的时候想的时候暴力去做,就是每次都找一下最后一个节点的前一个结点,然后修改指针,就是复杂度比较高
3.取逛了逛评论区,佬们还有一个思路我也觉得不错,就直接双端队列将元素全部加进去,然后前面后面分别来一个,构成新的链表,这样简单无脑,笔者觉得这个思路也很好
灵神思路中可能的疑惑?
1.为啥要找中间节点?
我觉得是因为中间结点刚好是不需要放到前面去的最后一个节点,它之后的节点都得放到前面去,不管n是奇数还是偶数
2.为啥要反转链表?
这样可以更好的找到最后一个节点,即要放到前面的节点,不需要和暴力做法一样每次都去遍历一次
完整代码:
cpp
class Solution {
public:
//876.链表的中间节点
ListNode* middleNode(ListNode* head) {
ListNode *l=head;
ListNode *r=head;
while(r!=nullptr&&r->next!=nullptr)
{
l=l->next;
r=r->next->next;
}
return l;
}
//206.反转链表
ListNode* reverseList(ListNode* head) {
ListNode *p=head;
ListNode *pre=nullptr;
while(p!=nullptr)
{
ListNode* q=p->next;
p->next=pre;
pre=p;
p=q;
}
return pre;
}
void reorderList(ListNode* head) {
ListNode *mid=middleNode(head);
ListNode *head2=reverseList(mid);
while(head2->next)
{
ListNode* ntx1=head->next;
ListNode *ntx2=head2->next;
head->next=head2;
head2->next=ntx1;
head=ntx1;
head2=ntx2;
}
}
};