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
.
這道題是將一個鏈表分爲前後兩部分,前一部分小於目標元素,後一部分大於或等於目標元素,並且保持元素原來的相對位置不變。
和快拍的一步partition比較相似,但是思路完全不同。因爲快排是交換元素,這裏要求保持元素的相對順序不變。
要完成這個任務肯定要遍歷一遍鏈表,因此時間複雜度可以做到O(n),那就儘可能做到原址操作,空間複雜度做到O(1)。
用四個指針分別指向較大元素和較小元素的部分的頭和尾,就可以實現這一目標。很簡單。
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
ListNode *p = head;
ListNode *greater = NULL, *less = NULL, *g = NULL, *l = NULL;
while (NULL != p){
if (p->val >= x){
if (NULL == greater){
greater = p;
g = p;
}
else
{
g->next = p;
g = p;
}
}
else{
if (NULL == less){
less = p;
l = p;
}
else
{
l->next = p;
l = p;
}
}
p = p->next;
}
if (NULL == less)
return greater;
l->next = greater;
if (g)
g->next = NULL;
return less;
}
};
寫完之後發現代碼好不簡潔,又臭又長,那就只好用dummy了,代碼可以簡化很多,還可以以減少很所判斷。
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
ListNode *p = head;
ListNode *greater = new ListNode(0);
ListNode *less = new ListNode(0);
ListNode *g = greater, *l = less;
while (NULL != p){
if (p->val >= x){
g->next = p;
g = p;
}
else{
l->next = p;
l = p;
}
p = p->next;
}
if (g)
g->next = NULL;
l->next = greater->next;
return less->next;
}
};