{1,4,3,2,5,2},3
{1,2,2,4,3,5}
{1,2,3,4,1},5
{1,2,3,4,1}
class Solution { public: ListNode *partition(ListNode *head, int x) { if(head == NULL) return head; ListNode* p1 = new ListNode(INT_MIN); ListNode* p2 = new ListNode(INT_MIN); ListNode* pp1 = p1; ListNode* pp2 = p2; ListNode* pNode = head; while(pNode != NULL) { if(pNode->val < x) { pp1->next = pNode; pp1 = pp1->next; } else { pp2->next = pNode; pp2 = pp2->next; } pNode = pNode->next; } pp2->next = NULL; pp1->next = p2->next; return p1->next; } };
public class Solution { public ListNode partition(ListNode head, int x) { if(head==null) return null; ListNode dummy1=new ListNode(0); ListNode dummy2=new ListNode(0); ListNode curr1=dummy1; ListNode curr2=dummy2; while(head!=null){ if(head.val<x){ curr1.next=head; curr1=curr1.next; }else{ curr2.next=head; curr2=curr2.next; } head=head.next; } curr2.next=null;//这句很重要!链表最后一个元素如果小于x的话,那么curr2.next 不为null curr1.next=dummy2.next; return dummy1.next; } }
ListNode *partition(ListNode *head, int x) { // 添加dummynode ListNode *dummyHead = new ListNode(0); dummyHead->next = head; ListNode *pre_less = dummyHead, *p = dummyHead; while (p->next) { if (p->next->val < x) { if (p->next == pre_less->next) { pre_less = p->next; p = p->next; } else { ListNode *cur_less = p->next; p->next = cur_less->next; cur_less->next = pre_less->next; pre_less->next = cur_less; pre_less = pre_less->next; } } else { p = p->next; } } return dummyHead->next; }
看到的都是申请两个链表,先分后切。我这里贴出来我博客里面的,O(n)时间复杂度,O(1)空间复杂度。
[toc]
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的放到一个链表里面,不小于的放到另一个链表里面,这种答案感觉好没劲哦。所以最后我采用的是O(n)时间复杂度,O(1)空间复杂度的解法。
具体说来,还是用快慢指针遍历链表,slow指向连续小于x的最后一个元素,fast指向当前元素不小于x但是下个元素小于x的元素。理解清楚这两个指针的对应关系之后,我们很容易将fast指向的元素的下一个元素追加到slow之后,同时更新slow和fast的指。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
if(head == NULL)
return NULL;
ListNode *dummy = new ListNode(0);
dummy->next = head;
ListNode *fast = dummy;
ListNode *slow = dummy;
while(fast != NULL && fast->next != NULL){
if(fast->next->val >= x)
fast = fast->next;
else{
if(fast == slow){
fast = fast->next;
slow = slow->next;
}
else{
ListNode *tmp = fast->next;
fast->next = tmp->next;
tmp->next = slow->next;
slow->next = tmp;
slow = slow->next;
}
}
}
return dummy->next;
}
};
系列教程持续发布中,欢迎订阅、关注、收藏、评论、点赞哦~~( ̄▽ ̄~)~
完的汪(∪。∪)。。。zzz
public class Solution { public ListNode partition(ListNode head, int x) { if(head == null) return null; if(head.next == null) return head; ListNode allMax = new ListNode(x); //用来存所有大于等于x的临时链表的头节点 ListNode p1 = allMax; ListNode allMin = new ListNode(x); //用来存所有小于x的临时链表的头结点 ListNode p2 = allMin; ListNode headNext = head.next; while(headNext != null) { //遍历传入的链表 if(head.val >= x) { //将所有大于等于x的节点挂在allMax链后,移动p1实现 p1.next = head; p1 = p1.next; } else { //将所有小于x的节点挂在allMin链后,移动p2实现 p2.next = head; p2 = p2.next; } headNext = head.next; head.next = null; //要断开原链的链接关系 head = headNext; } p2.next = allMax.next; //跨过allMax头结点,链接两个链表 return allMin.next; } }
ListNode *partition(ListNode *head, int x) { ListNode* p = head; vector<int> tmp; while(p!=NULL) { if(p->val < x) tmp.push_back(p->val); p = p->next; } p = head; while(p!=NULL) { if(p->val >= x) tmp.push_back(p->val); p = p->next; } p = head; for(int i = 0;i<tmp.size>val = tmp[i]; p = p->next; } return head; } </tmp.size></int>
ListNode *partition(ListNode *head, int x) { ListNode* p = head; ListNode* LVal = new ListNode(0); ListNode* GVal = new ListNode(0); ListNode* tmpL = LVal; ListNode* tmpG = GVal; while(p!=NULL) { if(p->val < x) { ListNode* node = new ListNode(p->val); tmpL->next = node; tmpL = tmpL->next; }else{ ListNode* node = new ListNode(p->val); tmpG->next = node; tmpG = tmpG->next; } p = p->next; } tmpL->next = GVal->next; return LVal->next; }
用了个蠢方法,在原链表上操作。
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
if(head==NULL)
return head;
ListNode *dummy=new ListNode(-100000);
dummy->next=head;
ListNode* insert=dummy;
ListNode*cur=head;
ListNode*pre=dummy;
while(cur){
if(cur->val<x&&pre->val>=x){
ListNode*temp=cur->next;
pre->next=cur->next;
cur->next=insert->next;
insert->next=cur;
cur=temp;
insert=insert->next;
}else if(cur->val<x&&pre->val<x){
insert=cur;
pre=cur;
cur=cur->next;
}
else{
pre=cur;
cur=cur->next;
}
}
return dummy->next;
}
};
import java.util.*; public class Solution { /* 思路:将这张链表拆分成两张一小一大的链表,再将这两种链表链接起来 */ public ListNode partition (ListNode head, int x) { // 首先创建两个哑节点,这样能够统一插入操作的代码 ListNode dummy_small = new ListNode(0), dummy_other = new ListNode(0); // 不直接修改哑节点的指向,因此使用cur_xxx指针代替 ListNode cur_small = dummy_small, cur_large = dummy_other; // 从头到尾遍历一次链表,小于x的挂在cur_small后面 // 大于x的挂在cur_large后面 while(head != null){ if(head.val < x){ cur_small.next = head; cur_small = head; }else{ cur_large.next = head; cur_large = head; } head = head.next; } // 最后将两张链表拼接起来 // 【这里需要注意的是,是将小的链表的最后节点指向大的链表的头节点,而不是最后的节点】 cur_small.next = dummy_other.next; // 大的链表最后节点的指向应该置为null cur_large.next = null; return dummy_small.next; } }
/** * struct ListNode { * int val; * struct ListNode *next; * }; */ class Solution { public: /** * * @param head ListNode类 * @param x int整型 * @return ListNode类 */ ListNode* partition(ListNode* head, int x) { // write code here ListNode *smallHead = NULL, *smallTail = NULL; ListNode *bigHead = NULL, *bigTail = NULL; while (head) { if (head->val < x) { if (smallHead == NULL) { smallHead = head; smallTail = head; } else { smallTail->next = head; smallTail = head; } } else { if (bigHead == NULL) { bigHead = head; bigTail = head; } else { bigTail->next = head; bigTail = head; } } head = head->next; } if (smallTail == NULL && bigTail == NULL) return NULL; if (smallTail == NULL) return bigHead; if (bigTail == NULL) return smallHead; smallTail->next = bigHead; bigTail->next = NULL; return smallHead; } };
/* 链表真的太烦了。 要加强对象和引用的理解以及区分。 */ public class Solution { public ListNode partition(ListNode head, int x) { ListNode list1 = new ListNode(0); ListNode list2 = new ListNode(0); ListNode cur1 = list1, cur2 = list2; ListNode cur = head; while (cur != null) { if (cur.val < x) { cur1.next = cur; cur1 = cur1.next; } else { cur2.next = cur; cur2 = cur2.next; } cur = cur.next; } cur1.next = list2.next; cur2.next = null; return list1.next; } }
时间复杂度为o(n),空间复杂度为o(1) public class Solution { public ListNode partition(ListNode head, int x) { if(head==null) return null; ListNode head0=new ListNode(0); head0.next=head; ListNode prev=head0; ListNode flag=head0; while(head != null) { if(head.val<x) { if(head==prev.next) { prev=prev.next; head=head.next; flag=flag.next; } else { flag.next=head.next; ListNode tmp=prev.next; prev.next=head; head.next=tmp; prev=prev.next; head=flag.next; } } else { head=head.next; flag=flag.next; } } return head0.next; } }
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *partition(ListNode *head, int x) { ListNode *less = new ListNode(0); ListNode *greater = new ListNode(1); ListNode *iter = head; ListNode *pLess = less, *pGreater = greater; while (iter != NULL) { if (iter->val < x) { pLess->next = iter; pLess = pLess->next; } if (iter->val >= x) { pGreater->next = iter; pGreater = pGreater->next; } iter = iter->next; } pGreater->next = NULL; pLess->next = greater->next; ListNode *re = less->next; delete less; delete greater; return re; } };
class Solution { public: ListNode *partition(ListNode *head, int x) { if(head==NULL) return NULL; ListNode* dummy=new ListNode(0); dummy->next=head; ListNode* pre=dummy; ListNode* last=dummy; while(pre->next!=NULL) { if(pre->next->val>=x) { break; } pre=pre->next; last=last->next; } while(last->next!=NULL) { if(last->next->val<x) { ListNode* tem=last->next->next; last->next->next=pre->next; pre->next=last->next; last->next=tem; pre=pre->next; continue; } last=last->next; } return dummy->next; } };
思想不太一样
public class Solution {
public ListNode partition(ListNode head, int x) {
if(head==null){
return null;
}
//找到第一个>=x的节点firstHigh,以后<x的节点就顺序插入firstHigh前
//考虑到有可能是head,所有准备个preHead节点
ListNode preHead = new ListNode(0);
preHead.next = head;
ListNode firstHigh = head,preHigh = preHead,node=head,preNode=preHead;
while(node!=null){
if(node.val>=x){
firstHigh = node;
preNode = node;
node = node.next;
break;
}
preNode = preHigh = node;
node = node.next;
}
while(node!=null){
if(node.val<x){
preNode.next = node.next;
node.next = firstHigh;
preHigh.next = node;
preHigh = node;
node = preNode;
}
preNode = node;
node = node.next;
}
return preHead.next;
}
}
class Solution { public: ListNode *partition(ListNode *head, int x) { if(head == NULL) return NULL; ListNode *L1 = new ListNode(0); ListNode *L2 = new ListNode(0); ListNode *p1 = L1; ListNode *p2 = L2; ListNode *p = head; while(p != NULL) { if(p->val < x) { p1->next = p; p1 = p1->next; }else{ p2->next = p; p2 = p2->next; } p = p->next; } p2->next = NULL; p1->next = L2->next; return L1->next; } };
class Solution { public: // 双指针 ListNode *partition(ListNode *head, int x) { ListNode *fake1 = new ListNode(0); ListNode *fake2 = new ListNode(0); ListNode *p1 = fake1,*p2=fake2; while(head) { if(head->val < x) { p1->next = head; p1 = p1->next; } else { p2->next = head; p2 = p2->next; } head = head->next; } p2->next = nullptr; p1->next = fake2->next; return fake1->next; } };
class Solution { public: ListNode *partition(ListNode *head, int x) { vector<int> d1,d2; int i; ListNode *p; for(p=head;p;p=p->next) if(p->val<x) d1.push_back(p->val); else d2.push_back(p->val); for(p=head,i=0;i<d1.size();p->val=d1[i],i++,p=p->next); for(i=0;i<d2.size();p->val=d2[i],i++,p=p->next); return head; } };
题意:给定一个单链表和一个x,把链表中小于x的放到前面,大于等于x的放到后面,每部分元素的原始相对位置不变。
思路:新建两个节点preHead1与preHead2,分别为指向两个链表的头结点。
把节点值小于x的节点链接到链表1上,节点值大等于x的节点链接到链表2上。
public ListNode partition(ListNode head, int x) { //preHead1与preHead2分别为两个链表头结点的前移节点(一个链表的节点值小于x,另一个大于等于x) ListNode preHead1 = new ListNode(0), preHead2 = new ListNode(0); ListNode cur1 = preHead1, cur2 = preHead2; while (head != null) { if (head.val < x) { cur1.next = head; cur1 = cur1.next; } else { cur2.next = head; cur2 = cur2.next; } head = head.next; } cur1.next = preHead2.next; cur2.next = null; return preHead1.next; }
public class Solution { public ListNode partition(ListNode head, int x) { if(head==null) return head; ListNode dummy=new ListNode(0),p=dummy; dummy.next=head; while(p.next!=null&&p.next.val<x) p=p.next; ListNode q = p,pre=p; while(q.next!=null) { pre=q;q=q.next; if(q.val<x) { pre.next=q.next; q.next=p.next; p.next=q; p=q; } } return dummy.next; } }