编写程序以 x 为基准分割链表,使得所有小于 x 的节点排在大于或等于 x 的节点之前。如果链表中包含 x,x 只需出现在小于 x 的元素之后(如下所示)。分割元素 x 只需处于“右半部分”即可,其不需要被置于左右两部分之间。
示例:
输入: head = 3->5->8->5->10->2->1, x = 5
输出: 3->1->2->10->5->5->8
/**
* 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) {
if(head == null || head.next == null ){
return head;
}
ListNode h = head, p = head;
LinkedList<ListNode> list = new LinkedList<>();
while(head != null ) {
if(head.val < x){
list.add(head);
}
head = head.next;
}
head = p;
while(head != null){
if(head.val >= x){
list.add(head);
}
head = head.next;
}
h = list.get(0);
for(int i=0; i< list.size()-1; i++){
p = list.get(i);
p.next = list.get(i+1);
p = p.next;
}
p.next = null;
return h;
}
}
上面这个揭发太挫了,看了题解,发现可以用双指针来做,前面的指针一直指着大于等于target的节点的前一个节点,后一个指针一直判断其指向接待你的后一个节点是小于target还是大于等于target,如果是前者,那么就将该节点移到前面指针后面,如果是后者那么就不管,继续遍历即可。新的题解如下:
class Solution {
public ListNode partition(ListNode head, int x) {
if(head == null || head.next == null ){
return head;
}
ListNode pre = new ListNode(-1);
pre.next = head;
ListNode front = pre;
boolean flag = false;
// 首先将front指向第一个大于等于x的节点前面
while(front.next != null && front.next.val < x){
front = front.next;
flag = true;
}
// front指向的节点大于等于x
if(!flag){
front = front.next;
}
while(front.next != null ) {
if(front.next.val >= x){
front = front.next;
}else{
ListNode moveNode = front.next;
front.next = moveNode.next;
ListNode firstBig = pre.next;
pre.next = moveNode;
moveNode.next = firstBig;
}
}
return pre.next;
}
}