- Partition List
中文English
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.
Example
Example 1:
Input: list = null, x = 0
Output: null
Explanation: The empty list Satisfy the conditions by itself.
Example 2:
Input: list = 1->4->3->2->5->2->null, x = 3
Output: 1->2->2->4->3->5->null
Explanation: keep the original relative order of the nodes in each of the two partitions.
注意这题好像不能简单的用双指针,然后用swap value的办法把大于x的节点跟小于x的节点相交换,我试了很久没有调出来,不知有没有高手用这个方法搞定了?
解法1:也是双指针法,先找到第一个>=x的节点,然后把p1,p2都初始化为其前面一个节点,然后p1永远指向第一个>=x的节点的前面那个节点,p2往后移动。
这个方法就是链表操作,但感觉调通很不容易。
注意:
- 加个dummyHead。不然如果第一个节点就>=x不好办。
-
- p2 初始化为 pre 而不是pre->next。不然在某些情况下出错。哪些情况还没细分析。
代码如下:
/**
* Definition of singly-linked-list:
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param head: The first node of linked list
* @param x: An integer
* @return: A ListNode
*/
ListNode * partition(ListNode * head, int x) {
if (!head || !head->next) return head;
ListNode *dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode * pre = dummyHead; //pre of the 1st node >= x
while(pre->next) {
if (pre->next->val >= x) {
break;
}
pre = pre->next;
}
ListNode * p1 = pre, * p2 = pre;//->next;
while(p2->next) {
if (p2->next->val < x) {
ListNode * temp = p2->next;
p2->next = temp->next;
temp->next = p1->next;
p1->next = temp;
p1 = p1->next;
} else {
p2 = p2->next;
}
}
return dummyHead->next;
}
};
解法2:
思路比解法1简单。就是用两个链表分别装<x和>=x的节点,然后拼起来。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode *dummy1 = new ListNode(0), *p1 = dummy1;
ListNode *dummy2 = new ListNode(0), *p2 = dummy2;
ListNode *p = head;
while(p) {
if (p->val >= x) {
p1->next = new ListNode(p->val);
p1 = p1->next;
} else {
p2->next = new ListNode(p->val);
p2 = p2->next;
}
p = p->next;
}
p2->next = dummy1->next;
return dummy2->next;
}
};
本文详细解析了链表分区算法的两种实现方法:通过双指针调整节点位置和使用两个链表分别存储再合并。提供了具体代码示例,帮助读者理解如何在链表中根据给定值x将所有小于x的节点置于大于等于x的节点之前,同时保持各分区内的相对顺序。
945

被折叠的 条评论
为什么被折叠?



