Medium!
題目描述:
給定一個鏈表和一個特定值 x,對鏈表進行分隔,使得所有小於 x 的節點都在大於或等於 x 的節點之前。
你應當保留兩個分區中每個節點的初始相對位置。
示例:
輸入: head = 1->4->3->2->5->2, x = 3 輸出: 1->2->2->4->3->5
解題思路:
這道題要求我們划分鏈表,把所有小於給定值的節點都移到前面,大於該值的節點順序不變,相當於一個局部排序的問題。那么可以想到的一種解法是首先找到第一個大於或等於給定值的節點,用題目中給的例子來說就是先找到4,然后再找小於3的值,每找到一個就將其取出置於4之前即可
C++解法一:
1 class Solution { 2 public: 3 ListNode *partition(ListNode *head, int x) { 4 ListNode *dummy = new ListNode(-1); 5 dummy->next = head; 6 ListNode *pre = dummy, *cur = head;; 7 while (pre->next && pre->next->val < x) pre = pre->next; 8 cur = pre; 9 while (cur->next) { 10 if (cur->next->val < x) { 11 ListNode *tmp = cur->next; 12 cur->next = tmp->next; 13 tmp->next = pre->next; 14 pre->next = tmp; 15 pre = pre->next; 16 } else { 17 cur = cur->next; 18 } 19 } 20 return dummy->next; 21 } 22 };
這種解法的鏈表變化順序為:
1 -> 4 -> 3 -> 2 -> 5 -> 2
1 -> 2 -> 4 -> 3 -> 5 -> 2
1 -> 2 -> 2 -> 4 -> 3 -> 5
此題還有一種解法,就是將所有小於給定值的節點取出組成一個新的鏈表,此時原鏈表中剩余的節點的值都大於或等於給定值,只要將原鏈表直接接在新鏈表后即可。
C++解法二:
1 class Solution { 2 public: 3 ListNode *partition(ListNode *head, int x) { 4 if (!head) return head; 5 ListNode *dummy = new ListNode(-1); 6 ListNode *newDummy = new ListNode(-1); 7 dummy->next = head; 8 ListNode *cur = dummy, *p = newDummy; 9 while (cur->next) { 10 if (cur->next->val < x) { 11 p->next = cur->next; 12 p = p->next; 13 cur->next = cur->next->next; 14 p->next = NULL; 15 } else { 16 cur = cur->next; 17 } 18 } 19 p->next = dummy->next; 20 return newDummy->next; 21 } 22 };
此種解法鏈表變化順序為:
Original: 1 -> 4 -> 3 -> 2 -> 5 -> 2
New:
Original: 4 -> 3 -> 2 -> 5 -> 2
New: 1
Original: 4 -> 3 -> 5 -> 2
New: 1 -> 2
Original: 4 -> 3 -> 5
New: 1 -> 2 -> 2
Original:
New: 1 -> 2 -> 2 -> 4 -> 3 -> 5