题目描述
- Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
- You should preserve the original relative order of the nodes in each of the two partitions.
For example:
- Given 1->4->3->2->5->2 and x = 3;
- return 1->2->2->4->3->5.
给定一个链表和一个值x,对它进行分区,使得小于x的所有节点都在大于或等于x的节点之前出现。
- 您应该保留两个分区中的每个节点的原始相对顺序。
- 例如:
- 输入:1->4->3->2->5->2 and x = 3;
- 输出:1->2->2->4->3->5
解题思路
- 本题我们最容易想到的思路是:新建两个链表,遍历原链表,每遍历一个节点就将该节点的值进行比较,将大于x和小于x的节点分别链到两条新的链表中,然后将两条链表进行连接,返回结果即为题目要求的链表
- 我们可以考虑一下双指针的解法,通过设置快慢指针,使得的慢指针指向连续小于x的最后一个元素,快指针指向当前元素不小于x但是下一个元素小于x的元素,则我们通过将fast指针连接在slow后面就可得到题目中要求的结果了
- 理清思路之后,我们就可以开始写代码了
代码实现
- 思路一实现:
ListNode *partition(ListNode *head, int x)
{
ListNode* lefthead = new ListNode(-1);
ListNode* righthead = new ListNode(-1);
ListNode* left = lefthead;
ListNdoe* right = righthead;
ListNode* cur = head;
while(cur != NULL)
{
if(cur->cur < x)
{
left->next = cur;
left = left->next;
}
else
{
right->next = cur;
right = right->next;
}
cur = cur->next;
}
left->next = righthead->next;
right->next = NULL;
return lefthead->next;
}
- 思路二实现:
ListNode *partition(ListNode *head, int x)
{
if(head == NULL)
return head;
//为fast指针建立一个前驱节点
ListNode* prev = new ListNode(-1);
prev->next = head;
//fast指针指向当前元素不大于x但是下一个节点小于x的元素
ListNode* fast = prev;
//slow指向连续小于x的最后一个元素
ListNode* slow = prev;
while(fast != NULL && fast->next != NULL)
{
if(fast->next->val >= x)
fast = fast->next;
else
{
if(fast == slow)
{
fast = fast->next;
slow = slow->next;
}
else
{
ListNode* tmp = fast->next;
fast->next = tmp->next;
tmp->next = slow->next;
slow->next = tmp;
slow = slow->next;
}
}
}
return prev->next;
}
- 完整实现代码如下:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
void PrintList(ListNode* head)
{
while (head != NULL)
{
printf("%d ->", head->val);
head = head->next;
}
printf("over\n");
}
//1->4->3->2->5->2 x=3
//1->2->2->4->3->5
//ListNode *partition(ListNode *head, int x)
//{
// ListNode* lefthead = new ListNode(-1);
// ListNode* righthead = new ListNode(-1);
// ListNode* left = lefthead;
// ListNode* right = righthead;
//
// ListNode* cur = head;
// while (cur != NULL)
// {
// if (cur->val < x)
// {
// left->next = cur;
// left = left->next;
// }
// else
// {
// right->next = cur;
// right = right->next;
// }
// cur = cur->next;
// }
// left->next = righthead->next;
// right->next = NULL;
// return lefthead->next;
//}
ListNode *partition(ListNode *head, int x) {
if (head == NULL)
return NULL;
ListNode *dummy = new ListNode(-1);
dummy->next = head;
ListNode *fast = dummy;
ListNode *slow = dummy;
while (fast != NULL && fast->next != NULL) {
if (fast->next->val >= x)
fast = fast->next;
else {
if (fast == slow) {
fast = fast->next;
slow = slow->next;
}
else {
ListNode *tmp = fast->next;
fast->next = tmp->next;
tmp->next = slow->next;
slow->next = tmp;
slow = slow->next;
}
}
}
return dummy->next;
}
int main()
{
ListNode* node1 = new ListNode(1);
ListNode* node2 = new ListNode(4);
ListNode* node3 = new ListNode(3);
ListNode* node4 = new ListNode(2);
ListNode* node5 = new ListNode(5);
ListNode* node6 = new ListNode(2);
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = node5;
node5->next = node6;
PrintList(node1);
ListNode* node = partition(node1, 3);
PrintList(node);
return 0;
}
- 程序运行结果如下所示: