86. 分隔链表
思路
首先遍历链表,将小节点下标存入一个数组,大节点和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) {
vector<int> vec_max,vec_min,vec;
ListNode* L=head;
int a = 0;
while(L){//拼数组,vec_min小节点下标数组,vec_max大节点下标数组
if(L->val>=x) vec_max.push_back(a);
else vec_min.push_back(a);
vec.push_back(L->val);
a++;
L=L->next;
}
for(int i=0;i<vec_max.size();i++){//拼在一起
vec_min.push_back(vec_max[i]);
}
int* nums = new int[vec.size()];
for(int k=0;k<vec_min.size();k++){//利用静态数组重新排列
nums[k] = vec[vec_min[k]];
//cout<<nums[k]<<endl;
}
int m = 0;
L=head;
while(L){//将静态数组的值赋值给原链表
L->val = nums[m];
m++;
L=L->next;
}
return head;
}
};
官方思路
官方开了两个链表,比我开四个数组强得多。。
直观来说我们只需维护两个链表 smallsmall 和 largelarge 即可,smallsmall 链表按顺序存储所有小于 xx 的节点,largelarge 链表按顺序存储所有大于等于 xx 的节点。遍历完原链表后,我们只要将 smallsmall 链表尾节点指向 largelarge 链表的头节点即能完成对链表的分隔。
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* small = new ListNode(0);
ListNode* smallHead = small;
ListNode* large = new ListNode(0);
ListNode* largeHead = large;
while (head != nullptr) {
if (head->val < x) {
small->next = head;
small = small->next;
} else {
large->next = head;
large = large->next;
}
head = head->next;
}
large->next = nullptr;
small->next = largeHead->next;
return smallHead->next;
}
};