LeetCode143重排链表

本文探讨了两种链表重新排序的方法:一种是通过栈实现,将右半区压入并合并,另一种是原地反转后半区。作者详细解析了合并过程中的关键操作,并分享了每种方法的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法一找到中间后,右半区压入栈中,然后将两部分合并

class Solution {
public:
    void reorderList(ListNode* head) {
        ListNode* fast = head;
        ListNode* slow = head;
        ListNode* mid;
        stack<ListNode*> st;
        while (fast->next != NULL && fast->next->next != NULL) {
            slow = slow->next;
            fast = fast->next->next;
        }
        mid = slow;
        slow = slow->next;
        mid->next = NULL;
        while (slow != NULL) {
            st.push(slow);
            slow = slow->next;
        }
        while (head != NULL) {
            ListNode* nex = head->next;
            if (!st.empty()) {
                ListNode* ss = st.top();
                st.pop();
                ss->next = nex;
                head->next = ss;
                head = head->next;
                head = head->next;
            }
            else {
                head = head->next;
            }
        }
    }
};

值得注意的点就是两部分链表合并时出现的问题,采用弹出一个栈中的节点,就将他的前驱和后继都搞定,此时head的位置需要后移两个位置,才能到达新的节点。当栈中元素全部弹出,那么只需将head后移,就可以跳出循环。此处的解决方法,真的烦了我一整天。

方法二 将后半区原地反转,空间复杂度O(1)

class Solution {
public:
	void reorderList(ListNode* head) {
		ListNode* fast = head;
		ListNode* slow = head;
		while (fast->next != NULL && fast->next->next != NULL) {
			slow = slow->next;
			fast = fast->next->next;
		}
		ListNode* mid = slow;
		ListNode* cur = slow->next;
		mid->next = NULL;
		ListNode* next = NULL;
		ListNode* newhead = NULL;
		while (cur != NULL) {
			next = cur->next;
			cur->next = newhead;
			newhead = cur;
			cur = next;
		}
		while (head != NULL && newhead != NULL) {
			ListNode* temp1 = head->next;
			ListNode* temp2 = newhead->next;
			head->next = newhead;
			head = temp1;
			newhead->next = head;
			newhead = temp2;
		}
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值