題幹
partition-list
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,
Given1->4->3->2->5->2and x = 3,
return1->2->2->4->3->5.
鏈表分治:給定一個數x,把鏈表中的數進行分類,比x小的放在左面,比x大的放在右面,並且保持鏈表結點的相對位置。
數據結構
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
解題思路
問題一
兩種思路,
1.題目沒有要求,則可以將原鏈表拆成兩個鏈表,一個比x小,一個比x大,只需要對鏈表進行遍歷,然後拆分即可。
2.題目如果有in-place這種要求的話不允許開闢新的鏈表空間,則要用兩個指針進行標記,一個爲cur爲當前討論的結點,另一個tmp爲最後一個小於x的結點的標記,如果cur的val小於x,則插入到tmp之後,後面cur前後兩個結點相接。
參考代碼
方法一:
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
if(head==NULL)
return head;
ListNode *head1=new ListNode(0),*head2=new ListNode(0);
ListNode *cur1=head1,*cur2=head2;//兩個鏈表頭
while(head!=NULL)
{
if(head->val<x)
{
cur1->next=head;
cur1=cur1->next;
}
else
{
cur2->next=head;
cur2=cur2->next;
}
head=head->next;
}
cur2->next=NULL;//拼接鏈表
cur1->next=head2->next;//這裏一定注意把鏈表2的尾部置爲NULL
return head1->next;
}
};
方法二:
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
if(head==NULL)
return head;
ListNode *pre=new ListNode(0);//僞頭
pre->next=head;
ListNode *tmp=pre,*cur=pre;
while (cur->next!=NULL)
{
if(cur->next->val<x)//結點的val小於x
{
if(cur==tmp)//這裏如果在起點的話要單獨討論,不需要進行結點的插入和刪除
{
cur=cur->next;
tmp=tmp->next;
}
else//結點的插入和刪除
{
ListNode *p=tmp->next;
tmp->next=cur->next;
cur->next=cur->next->next;
tmp=tmp->next;
tmp->next=p;
}
}
else
cur=cur->next;
}
return pre->next;//返回頭部
}
};
方法討論
方法一沒有特殊的,方法二在進行寫代碼的時候要討論的結點爲cur->next,因爲當後面進行刪除和拼接的時候如果用當前結點來討論的話無法找到前面的結點。
易錯點
1.方法一鏈表2的最後要置爲NULL.
2.方法二兩個標誌要開始進行初始化,並且討論的起始點要單獨來確定。