题目:
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.
Example:
Input: head = 1->4->3->2->5->2, x = 3
Output: 1->2->2->4->3->5
这道题的题意是给一个值x,然后将所有小于x的节点放到大于等于x的节点前面
如在题目给的例子中x=3,比3小的节点有1 、2、2
第一个大于等于x的节点为4,其中节点1已经在4前面了,不用管它,只需要将两个2节点移到4前面即可
解法1:
首先我们先找到第一个大于等于x的节点,然后在它之后找比x小的节点然后插入到x的前面,注意插入的顺序要与原链表的顺序保持一致
为了更好的插入节点,我们要用两个指针pre和cur,分别指向第一个大于等于x的节点的前面的节点和第一个大于等于x的节点,初始值为dummy节点和head节点
程序的第一部分:我们先找到第一个大于等于x的节点
第一种方法:遍历pre->next
一旦找到第一个大于等于x的节点,就设置cur为pre的下一个节点
这有个问题:1->1->2, x = 3,没有大于等于x的节点,最后要手动设置cur = pre->next;
while(pre->next){
if(pre->next->val >= x){
cur = pre->next;
break;
}
pre = pre->next;
}
cur = pre->next;
第二种方法:遍历cur 在遍历的过程中记录pre和cur
while(cur){
if(cur->val >= x){
break;
}
pre = cur;
cur = cur->next;
}
程序的第二部分:
从cur节点后进行遍历,找到小于x的节点将它插到前面,注意如果cur现在是空,直接返回即可,不需要判断
最后pre要往后移一位保证插入的时候的顺序保持不变
c++:
/**
* 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* dummy = new ListNode(-1);
dummy->next = head;
ListNode* pre = dummy;
ListNode* cur = head;
// while(pre->next){
// if(pre->next->val >= x){
// cur = pre->next;
// break;
// }
// pre = pre->next;
// }
// cur = pre->next;
while(cur){
if(cur->val >= x){
break;
}
pre = cur;
cur = cur->next;
}
if(!cur) return dummy->next;
while(cur->next){
if(cur->next->val < x){
ListNode* temp = cur->next;
cur->next = temp->next;
temp->next = pre->next;
pre->next = temp;
pre = pre->next;
}else{
cur = cur->next;
}
}
return dummy->next;
}
};
java:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
ListNode cur = head;
while(pre.next!=null){
if(pre.next.val >= x){
cur = pre.next;
break;
}
pre = pre.next;
}
cur = pre.next;
// while(cur!=null){
// if(cur.val >= x){
// break;
// }
// pre = cur;
// cur = cur.next;
// }
if(cur == null) return dummy.next;
while(cur.next!=null){
if(cur.next.val < x){
ListNode temp = cur.next;
cur.next = temp.next;
temp.next = pre.next;
pre.next = temp;
pre = pre.next;
}else{
cur = cur.next;
}
}
return dummy.next;
}
}
python:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
dummy = ListNode(-1)
dummy.next = head
pre = dummy
cur = head
# while pre.next:
# if pre.next.val >= x:
# cur = pre.next
# break
# pre = pre.next
# cur = pre.next
while cur:
if cur.val >= x:
break
pre = cur
cur = cur.next
if cur == None: return dummy.next
while cur.next:
if cur.next.val < x:
temp = cur.next
cur.next = temp.next
temp.next = pre.next
pre.next = temp
pre = pre.next
else:
cur = cur.next
return dummy.next
解法2:
遍历链表,将小于x的组成一个链表: 1->2->2
将大于等于x的组成一个链表: 4->3->5
将两者连接即可: 1->2->2->4->3->5
c++:
/**
* 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* min_head = new ListNode(-1);
ListNode* max_head = new ListNode(-1);
ListNode* left_cur = min_head;
ListNode* right_cur = max_head;
while(head){
if(head->val < x){
left_cur->next = head;
left_cur = head;
} else {
right_cur->next = head;
right_cur = head;
}
head = head->next;
}
right_cur->next = nullptr;
left_cur->next = max_head->next;
return min_head->next;
}
};
java:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode min_head = new ListNode(-1);
ListNode max_head = new ListNode(-1);
ListNode left_cur = min_head;
ListNode right_cur = max_head;
while(head != null){
if(head.val < x){
left_cur.next = head;
left_cur = head;
} else {
right_cur.next = head;
right_cur = head;
}
head = head.next;
}
right_cur.next = null;
left_cur.next = max_head.next;
return min_head.next;
}
}
python:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def partition(self, head, x):
"""
:type head: ListNode
:type x: int
:rtype: ListNode
"""
min_head = ListNode(-1)
max_head = ListNode(-1)
left_cur = min_head
right_cur = max_head
while head:
if head.val < x:
left_cur.next = head
left_cur = head
else:
right_cur.next = head
right_cur = head
head = head.next
right_cur.next = None
left_cur.next = max_head.next
return min_head.next