leecode 解题总结:86. Partition List

根据给定值x,将链表分为小于x和大于等于x两部分,保持原顺序。通过创建两个辅助链表l1和l2分别存储小于x和大于等于x的元素,最后将l1和l2连接。示例:输入6 3,1 4 3 2 5 2,输出1 2 2 4 3 5。
摘要由CSDN通过智能技术生成
#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值