分割链表
/* 面试题 02.04 :分割链表
* 题目描述:编写程序以 x 为基准分割链表,使得所有小于 x 的节点排在大于或等于 x 的节点之前。
* 如果链表中包含 x,x 只需出现在小于 x 的元素之后(如下所示)。
* 分割元素 x 只需处于“右半部分”即可,其不需要被置于左右两部分之间。
* 解题思路:本题要求将大于基准的数置于结点左侧,小于结点的置于结点右侧,该功能类似于快速排序
* 的分割操作(基准指向0,left指向1、right指向length-1,若right大于基准right前移
* 若right小于基准则停止,left小于基准后移大于基准停止,left、right同时停止交换
* left、right指向同一元素,交换基准于right)。但本题中要求的数据结构是链表,right的
* 前移操作不便进行,若要使用这种方案需将链表转化为数组,解决后再转化为链表,相较于在数组
* 上的解法,空间复杂度增加O(n)时间复杂度增加O(2n)
*
* 另一种思路:新增伪头结点,声明尾指针,小于基准的接入表头,大于基准的接入表尾
* */
public class PartitionList {
public static void main(String[] args) {
//head = 3->5->8->5->10->2->1, x = 5
ListNode head = new ListNode(3);
ListNode node1 = new ListNode(5);
ListNode node2 = new ListNode(8);
ListNode node3 = new ListNode(5);
ListNode node4 = new ListNode(10);
ListNode node5 = new ListNode(2);
ListNode node6 = new ListNode(1);
head.next=node1;
node1.next=node2;
node2.next=node3;
node3.next=node4;
node4.next=node5;
node5.next=node6;
PartitionListSolution solution = new PartitionListSolution();
ListNode p = solution.partition(node5, 5);
while(p!=null) {
System.out.print(p.val);
p=p.next;
}
}
}
class PartitionListSolution {
public ListNode partition(ListNode head, int x) {
ListNode abstractHead = new ListNode(-1);
abstractHead.next = null;
ListNode tail = abstractHead;
ListNode p = head;
ListNode temp = null;
while(p!=null) {
if(p.val<x) {
temp = p;
p=p.next;
temp.next=abstractHead.next;
abstractHead.next=temp;
if(abstractHead.next.next==null)tail = tail.next;
}else {
temp = p;
p=p.next;
temp.next = null;
tail.next=temp;
tail=tail.next;
}
}
return abstractHead.next;
}
}