力扣86. 分隔链表(双指针、哑结点)

力扣86. 分隔链表(双指针、哑结点)

https://leetcode-cn.com/problems/partition-list/

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

双指针

复杂度分析

  • 时间复杂度: O(N),其中NN是原链表的长度,我们对该链表进行了遍历。
  • 空间复杂度: O(1),我们没有申请任何新空间。值得注意的是,我们只移动了原有的结点,因此没有使用任何额外空间。

哑结点初始化

*`注意:` 由于我们从左到右遍历了原有链表,故两个链表中元素的相对顺序不会发生变化。另外值得注意的是,在图中我们完好地保留了原有链表。事实上,在算法实现中,我们将节点从原有链表中移除,并将它们添加到别的链表中。我们没有使用任何额外的空间,只是将原有的链表元素进行移动。*

image.png

#include "stdafx.h"
#include "stdafx.h"
#include <iostream>
#include <queue>
using namespace std;
struct ListNode
{
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

class Solution
{
public:
	//双指针,大小指针
	ListNode* partition(ListNode* head, int x)
	{
		ListNode* low=new ListNode(0);
		ListNode* lowhead = low;
		ListNode* high = new ListNode(0);
		ListNode* highhead = high;
		ListNode* cur = head;
		while (cur !=nullptr)
		{
			if (cur->val<x)
			{
				low->next = cur;
				low = low->next;
			}
			else
			{
				high->next = cur;
				high = high->next;
			}
			cur = cur->next;
		}
		low->next = highhead->next;
		high->next = nullptr;
		return lowhead->next;
	}
};

int main()
{
	Solution s;
	ListNode head[2] = { 1,4 };
	head[0].next = &head[1];
	//head[1].next = &head[2];
	//head[2].next = &head[3];
	//head[3].next = &head[4];
	//head[4].next = &head[5];
	ListNode* out1 = head;
	while (out1)
	{
		cout << out1->val << '\t';
		out1 = out1->next;
	}
	cout << '\n';
	auto result1 = s.partition(head, 0);
	ListNode* out2 = result1;
	while (out2)
	{
		cout << out2->val << '\t';
		out2 = out2->next;
	}
	cout << '\n';
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35683407/article/details/105852902