看到148题进阶要求nlogn的复杂度我首先想到的就是快排和归并排序
快排的话链表不像数组可以通过索引来移动元素位置,而归并排序是先划分到最小之后再排序合并,
所以这题我用归并的方法来解决
第一个问题是如何找到链表的中点?
这个问题我也不知道 但是思路就是要先找到中点
查了下 使用快慢指针的方法来找
即快指针每次向后移动两个节点,慢指针每次向后移动一个节点, 当快指针到末尾为空的时候 慢指针也就到达了中间
ListNode* get_mid(ListNode* head)
{
ListNode* fast = head;
ListNode* slow = head;
while (fast && fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
找到链表的中点之后我们就要开始划分了 要把每一个节点都变成孤立的节点
上代码:
ListNode* partition(ListNode* beg, ListNode* end)
{
if (beg == end)
{
return beg;
}
ListNode* mid = get_mid(beg);
ListNode* left = partition(beg, mid);
ListNode* right = partition(mid->next, end);
return merge_list(left, right);
}
有没有发现什么问题
这样分根本就没有拆掉链表,节点还是相连的
这也是我第一天一直没找到的原因…洗了算了
这样每次都要把中点的next置为空 这样拆分到最后 每个节点都是孤立的了
ListNode* partition(ListNode* beg, ListNode* end)
{
if (beg == end)
{
return beg;
}
ListNode* mid = get_mid(beg);
ListNode* right = partition(mid->next, end);
mid->next = nullptr;
ListNode* left = partition(beg, mid);
return merge_list(left, right);
}
拆分结束后 我们就要进行合并了
这个merge_list方法呢就是我们的21题 直接照抄
可以看21题的解答
这种递归拆分其实不要想的太多
只要想到打破这个循环的调件,然后就去实现这个循环只做一次的代码就好了,其他的不要多想.加油!!!