#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
/*
问题:
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.
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
分析:题目给定一个链表和一个值,用该值进行划分,所有小于该值的数都出现在大于等于该值的数的前面
,而且需要保持两个划分中相对顺序不能改变
快速排序的划分每次只是使得一个元素放到该放的位置上,并且左边的元素<=它,右边的元素>=它。
但是这个划分不是稳定的,因此快排的划分不能使用。
如果从前向后和从后向前碰到不符合的元素就交换,划分后会丢失链表某一侧的相对顺序。这个也不行。
从前向后遍历,
如果当前元素等于给定元素,说明当前元素前面部分已经必须是小于当前元素的,后续的所有元素必须是大于等于当前元素的;
此时将前面记录的大于给定值的元素放到当前元素的后面,如果后面遇到小于给定值的元素,就把该元素插入到当前元素前面一个元素处。
如果当前元素<给定元素,并且此时没有
维护一个小于当前元素的指针p,和大于当前元素的指针q。
上述太麻烦了。
设定两个链表l1,l2。l1中存放小于给定值的元素,l2中存放>=给定值的元素
最后l1的末尾连接l2的头部即可。
输入:
6(链表结点个数) 3(划分元素值)
1 4 3 2 5 2
1 3
1
2 3
1 4
输出:
1 2 2 4 3 5
1
1 4
关键:
1 对于无序划分使用快排的划分;对于需要保持相对顺序的划分,采用两个链表来做
设定两个链表l1,l2。l1中存放小于给定值的元素,l2中存放>=给定值的元素
最后l1的末尾连接l2的头部即可。
*/
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if(NULL == head)
{
return head;
}
ListNode* lessHead = NULL;
ListNode* lessTail = NULL;
ListNode* greaterHead = NULL;
ListNode* greaterTail = NULL;
ListNode* tempHead = head;
while(head)
{
if(head->val < x)
{
if(lessHead)
{
lessTail->next = head;
lessTail = head;
}
else
{
lessTail = lessHead = head;
}
}
else
{
if(greaterHead)
{
greaterTail->next = head;
greaterTail = head;
}
else
{
greaterTail = greaterHead = head;
}
}
head = head->next;
}
//设置两个链表末尾指针指向
if(lessTail != NULL)
{
lessTail->next = greaterHead;
}
if(greaterTail != NULL)
{
greaterTail->next = NULL;
}
head = tempHead;
if(lessHead)
{
return lessHead;
}
if(greaterHead)
{
return greaterHead;
}
}
};
void print(ListNode* head)
{
if(!head)
{
cout << "no result" << endl;
}
ListNode* tempHead = head;
while(head)
{
cout << head->val << " ";
head = head->next;
}
cout << endl;
head = tempHead;
}
ListNode* buildList(vector<int>& nums)
{
if(nums.empty())
{
return NULL;
}
int size = nums.size();
ListNode* head ;
ListNode *tail;
ListNode* node;
for(int i = 0 ; i < size ; i++)
{
if(i)
{
node = new ListNode(nums.at(i));
tail->next = node;
tail = node;
}
else
{
head = new ListNode(nums.at(i));
tail = head;
}
}
return head;
}
void deleteList(ListNode* head)
{
ListNode* node;
while(head)
{
node = head->next;
delete head;
head = node;
}
}
void process()
{
vector<int> nums;
int value;
int num;
Solution solution;
vector<int> result;
int x;
while(cin >> num >> x)
{
nums.clear();
for(int i = 0 ; i < num ; i++)
{
cin >> value;
nums.push_back(value);
}
ListNode* head = buildList(nums);
ListNode* newHead = solution.partition(head , x);
print(newHead);
deleteList(newHead);//删除节点了
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
leecode 解题总结:86. Partition List
最新推荐文章于 2022-05-05 15:59:42 发布
根据给定值x,将链表分为小于x和大于等于x两部分,保持原顺序。通过创建两个辅助链表l1和l2分别存储小于x和大于等于x的元素,最后将l1和l2连接。示例:输入6 3,1 4 3 2 5 2,输出1 2 2 4 3 5。
摘要由CSDN通过智能技术生成