Partition:编写代码,将链表中小于x
的元素放在链表的前半部分,大于x
的元素放在链表的后半部分,没有顺序要求。
如果是数组的话,根据x
对数组进行划分的方法类似于快排。对于链表会更简单一些,可以直接将原始链表拆分为两个链表,一个中所有元素比x
小,一个中所有元素比x
大,最后再进行连接。
通过在链表中使用beforeStartNode
和afterStartNode
作为头结点,可以简化插入的过程,同时为了稳定拆分,使用beforeEnd
和afterEnd
记录了尾节点,否则只能采用头插法。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode beforeStartNode(0), afterStartNode(0);
ListNode* beforeEnd = &beforeStartNode;
ListNode* afterEnd = &afterStartNode;
ListNode* iter = head;
while(iter != nullptr){
if(iter->val < x){
beforeEnd->next = iter;
beforeEnd = iter;
}
else{
afterEnd->next = iter;
afterEnd = iter;
}
iter = iter->next;
}
afterEnd->next = nullptr;
if(beforeStartNode.next == nullptr){
return afterStartNode.next;
}
beforeEnd->next = afterStartNode.next;
return beforeStartNode.next;
}
};
如果觉得这种方法过于复杂,也可以简单一些,但是会破坏稳定性。我们直接以第1
个元素作为枢纽元,从第2
个元素开始,将小于x
的元素放在枢纽元之前,将大于x
的元素放在枢纽元之后。无论枢纽元和x
是什么样的大小关系,结果都是正确的。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if(head == nullptr) return nullptr;
ListNode* pHead = head;
ListNode* pTail = head;
ListNode* iter = head->next;
ListNode* next;
while(iter != nullptr){
next = iter->next;
if(iter->val < x){
iter->next = pHead;
pHead = iter;
}
else{
pTail->next = iter;
pTail = iter;
}
iter = next;
}
pTail->next = nullptr;
return pHead;
}
};