力扣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),我们没有申请任何新空间。值得注意的是,我们只移动了原有的结点,因此没有使用任何额外空间。
哑结点初始化
*`注意:` 由于我们从左到右遍历了原有链表,故两个链表中元素的相对顺序不会发生变化。另外值得注意的是,在图中我们完好地保留了原有链表。事实上,在算法实现中,我们将节点从原有链表中移除,并将它们添加到别的链表中。我们没有使用任何额外的空间,只是将原有的链表元素进行移动。*
#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;
}