力扣: 21题合并两个有序链表和148题链表排序 踩坑!!!(c++)

在这里插入图片描述
在这里插入图片描述
看到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题的解答

这种递归拆分其实不要想的太多
只要想到打破这个循环的调件,然后就去实现这个循环只做一次的代码就好了,其他的不要多想.加油!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值