LeetCode 86. 分隔链表(Partition List)
题目描述
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
示例:
输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5
解题思路
采用双指针思想,维护left指针作为前面的插入指针,right作为后面的删除指针。此时分为两种情况:
- 若链表首节点值大于或等于给定值,则应首先找到其后第一个小于给定值的节点删除并插入到right之前作为头节点,并令left指向它,然后将right指向原删除节点的下一个节点
- 若链表首节点值小于给定值,那么首先找到从左往右第一个大于或等于给定值的节点right,并令left指向其前一个节点
这样从right开始依次向后遍历,每次找到一个小于给定值的节点,就将其删除并插入到left指向节点之后,然后令left指针右移一位,直到right指向NULL
代码
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* partition(ListNode* head, int x) { 12 if(head == NULL) return NULL; 13 ListNode *left = head, *right, *pre; 14 if(left->val >= x){ 15 pre = left; 16 right = pre->next; 17 while(right){ 18 if(right->val < x){ 19 pre->next = right->next; 20 right->next = left; 21 head = left = right; 22 right = pre->next; 23 break; 24 } 25 pre = right; 26 right = right->next; 27 } 28 if(right == NULL) return head; 29 } 30 else{ 31 while(left->next && left->next->val < x) 32 left = left->next; 33 right = left->next; 34 if(right == NULL) return head; 35 pre = right; 36 } 37 while(right){ 38 if(right->val < x){ 39 pre->next = right->next; 40 right->next = left->next; 41 left->next = right; 42 left = right; 43 right = pre->next; 44 continue; 45 } 46 pre = right; 47 right = right->next; 48 } 49 return head; 50 } 51 };