【LeetCode】37. Reorder List

题目描述(Medium)

Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

题目链接

https://leetcode.com/problems/reorder-list/description/

Example 1:

Given 1->2->3->4, reorder it to 1->4->2->3.

Example 2:

Given 1->2->3->4->5, reorder it to 1->5->2->4->3.

算法分析

通过快慢指针法找到中间节点并断开,将后半链表翻转,再合并两个单链表;

提交代码:

class Solution {
public:
	// 修改后
	void reorderList(ListNode* head) 
	{
		if (!head || !head->next) return;
		ListNode* slow = head, *fast = head, *prev = nullptr;
		while (fast && fast->next)
		{
			prev = slow;
			slow = slow->next;
			fast = fast->next->next;
		}

		prev->next = nullptr;
		// reverse
		slow = reverse(slow);
		// merge
		ListNode* curr = head;
		while (curr->next)
		{
			ListNode* temp = curr->next;
			curr->next = slow;
			slow = slow->next;
			curr->next->next = temp;
			curr = temp;
		}

		curr->next = slow;
	}

	// 修改前
	void reorderList1(ListNode* head) {
		if (!head || !head->next) return;
		int n = 0;
		for (ListNode* node = head; node != nullptr; node = node->next)
			++n;

		// 后半部分的起始坐标
		ListNode* sec_half = head;
		for (int i = 1; i < (n + 1) / 2; ++i)
			sec_half = sec_half->next;

		ListNode* head2 = sec_half->next;
		sec_half->next = nullptr;
		//翻转//

		head2 = reverse(head2);

		for (ListNode* node1 = head, *node2 = head2;
			node1 && node2;)
		{
			ListNode* next1 = node1->next;
			ListNode* next2 = node2->next;
			node1->next = node2;
			node2->next = next1;
			node1 = next1;
			node2 = next2;
		}
	}

	ListNode* reverse(ListNode* head)
	{
		ListNode* prev = head;
		for (ListNode* curr = prev->next, *next = curr ? curr->next : nullptr;
			curr;
			prev = curr, curr = next, next = next ? next->next : nullptr)
		{
			curr->next = prev;
		}

		head->next = nullptr;
		return prev;
	}
};

测试代码:

// ====================测试代码====================
void Test(const char* testName, ListNode* result, ListNode* expected)
{
	if (testName != nullptr)
		printf("%s begins: \n", testName);

	Solution s;
	s.reorderList(result);

	while (result && expected)
	{
		if (result->val != expected->val)
		{
			printf("failed\n");
			return;
		}

		result = result->next;
		expected = expected->next;
	}

	if(result || expected)
		printf("failed\n");
	else
		printf("passed\n");
}

int main(int argc, char* argv[])
{
	ListNode* node1 = new ListNode(1);
	ListNode* node2 = new ListNode(2);
	ListNode* node3 = new ListNode(3);
	ListNode* node4 = new ListNode(4);


	ConnectListNodes(node1, node2);
	ConnectListNodes(node2, node3);
	ConnectListNodes(node3, node4);

	ListNode* node5 = new ListNode(1);
	ListNode* node6 = new ListNode(4);
	ListNode* node7 = new ListNode(2);
	ListNode* node8 = new ListNode(3);

	ConnectListNodes(node5, node6);
	ConnectListNodes(node6, node7);
	ConnectListNodes(node7, node8);
	
	Test("Test1", node1, node5);


	ListNode* node9 = new ListNode(1);
	ListNode* node10 = new ListNode(2);
	ListNode* node11 = new ListNode(3);
	ListNode* node12 = new ListNode(4);
	ListNode* node13 = new ListNode(5);
	ConnectListNodes(node9, node10);
	ConnectListNodes(node10, node11);
	ConnectListNodes(node11, node12);
	ConnectListNodes(node12, node13);

	ListNode* node14 = new ListNode(1);
	ListNode* node15 = new ListNode(5);
	ListNode* node16 = new ListNode(2);
	ListNode* node17 = new ListNode(4);
	ListNode* node18 = new ListNode(3);
	ConnectListNodes(node14, node15);
	ConnectListNodes(node15, node16);
	ConnectListNodes(node16, node17);
	ConnectListNodes(node17, node18);

	Test("Test2", node9, node14);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/ansizhong9191/article/details/82258702