Partition List 题解
题目来源:https://leetcode.com/problems/partition-list/description/
Description
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
Given 1->4->3->2->5->2
and x = 3,
return 1->2->2->4->3->5
.
Solution
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if (head == NULL || head -> next == NULL)
return head;
ListNode *lowHead = NULL, *highHead = NULL;
ListNode *lowTail = NULL, *highTail = NULL;
// 找到最靠前的小于x的链表段头尾和大于x的链表段头尾
if (head -> val < x)
lowHead = lowTail = head;
else
highHead = highTail = head;
if (lowHead) {
while (lowTail -> next) {
if (lowTail -> next -> val < x) {
lowTail = lowTail -> next;
} else {
highHead = highTail = lowTail -> next;
break;
}
}
if (!highHead)
return head;
} else {
while (highTail -> next) {
if (highTail -> next -> val >= x) {
highTail = highTail -> next;
} else {
lowHead = lowTail = highTail -> next;
break;
}
}
if (!lowHead)
return head;
}
if (highHead == head) {
// 将小于x的链表段放到大于x的链表段前面
highTail -> next = lowTail -> next;
lowTail -> next = highHead;
}
// 每次向后探测一个节点,如果大于x则不移动,如果小于x就加到小于x的链表段尾部,
// 直到读取完整个链表
while (highTail -> next) {
if (highTail -> next -> val >= x) {
highTail = highTail -> next;
} else {
lowTail -> next = highTail -> next;
lowTail = lowTail -> next;
highTail -> next = lowTail -> next;
lowTail -> next = highHead;
}
}
return lowHead;
}
};
解题描述
这道题题意是给出一个链表和一个数x
,要求将链表中所有大于或等于x
的节点放到小于x
的节点后面,前变换位置前后,高低两个链表段内节点的顺序和原链表相同。上面是我自己AC的解法,算法已经写在注释中。虽然这个解法可以在一趟之内完成,但是相对比较繁琐,下面给出的是评论区的高票解法:
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if (head == NULL || head -> next == NULL)
return head;
ListNode *lowHead = new ListNode(0);
ListNode *highHead = new ListNode(0);
ListNode *lowTail = lowHead, *highTail = highHead;
while (head) {
if (head -> val < x) {
lowTail -> next = head;
lowTail = lowTail -> next;
} else {
highTail -> next = head;
highTail = highTail -> next;
}
head = head -> next;
}
highTail -> next = NULL;
lowTail -> next = highHead -> next;
head = lowHead -> next;
delete lowHead;
delete highHead;
return head;
}
};
其采用的办法是对原来的链表构建2个新的链表low
和high
,然后从前向后扫描链表,每次根据节点元素大小分别放到两个新链表尾部,最后再将high
接到low
后面即可。