编写程序以 x 为基准分割链表,使得所有小于 x 的节点排在大于或等于 x 的节点之前。如果链表中包含 x,x 只需出现在小于 x 的元素之后(如下所示)。分割元素 x 只需处于“右半部分”即可,其不需要被置于左右两部分之间。
示例:
输入: head = 3->5->8->5->10->2->1, x = 5
输出: 3->1->2->10->5->5->8
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: //删除某个节点比返回该节点指针 ListNode* del(ListNode* node,ListNode* pre){ if(node != nullptr){ pre->next = node->next; node->next = nullptr; } return node; } //头插、尾差、双指针三种方法都实现 ListNode* partition(ListNode* head, int x) { //3 5 8 10 2 1 5 ListNode* dummy = new ListNode(-1); dummy->next = head; ListNode* pre = dummy; while(head){ if(head->val >= x){ pre = head; head = head->next; }else{ ListNode* node = del(head,pre); head = pre->next; node->next = dummy->next; dummy->next = node; if(pre == dummy) pre = pre->next; } } return dummy->next; } };
//尾插法:注意几点,到之前的end就要结束了,不能等到了end,因为end一直在后移动
//end后移注意 end = node。指end指向新的node
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* del(ListNode* node,ListNode* pre){ if(node){ pre->next = node->next; node->next = nullptr; } return node; } //尾插法,顺序与之前一致 ListNode* partition(ListNode* head, int x) { //3 5 8 5 10 2 1 //可以先找到尾部 ListNode* hTmp = head; ListNode* end = head; while(head){ end = head; head = head->next; } ListNode* dummy = new ListNode(-1); dummy->next = hTmp; ListNode* pre = dummy; //到end之前.这里容易出bug,end回后移 ListNode* PreEnd = end; while(hTmp != PreEnd){ if(hTmp->val < x){ pre = hTmp; hTmp = hTmp->next; }else{ ListNode* node = del(hTmp,pre); hTmp = pre->next; end->next = node; end = node; } } return dummy->next; } };
//双指针法
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* del(ListNode* node,ListNode* pre){ if(node != nullptr){ pre->next = node->next; node->next = nullptr; } return node; } //双指针法:前指针指向小yu X的最后一个节点 //后指针为当前指针,>= X的话就继续后移 ListNode* partition(ListNode* head, int x) { ListNode* pre = new ListNode(-1); pre->next = head; ListNode* cur = head; ListNode* PreCur = pre; ListNode* dummy = pre; // 3 5 8 5 2 1 5 while(cur){ if(cur->val < x){ ListNode* node = del(cur,PreCur); //cur移动 cur = PreCur->next; //插入node node->next = pre->next; pre->next = node; pre = node; if(PreCur->next != cur){ PreCur = pre; } }else{ PreCur = cur; cur = cur->next; } } return dummy->next; } };