Question
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,
Given 1->4->3->2->5->2
and x = 3,
return 1->2->2->4->3->5
.
本题难度Medium。
【要求】
You should preserve the original relative order of the nodes in each of the two partitions. 在两个区段内不允许打乱原有次序。
【复杂度】
时间 O(N) 空间 O(1)
【思路】
开始的思路:找两个List,一个放小于x的ListNode的值,一个放大于等于x的ListNode的值,然后遍历一遍链表;接着再利用两个List的值给链表重新赋值。缺点:空间复杂度O(N)
更好的思路:遍历一遍链表,把小于x的都挂到lessHead
后,把大于等于x的都放到largeHead
后,最后再把largeHead.next
挂到小于链表的后面就可以了。
【注意】
“第2个代码”中:17行large.next=null;
它是为了对付:..->3->2
这种情况。遍历完毕后,less链表和large链表分别为:
lessHead->..->2
largeHead->..->3->2
看到了吧,3是最后一个节点,其next应为null
而不该再指向2
。
【第1个代码】
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode partition(ListNode head, int x) {
//require
List<Integer> smalls=new LinkedList<>(),bigs=new LinkedList<>();
ListNode cur=head;
//invariant
while(cur!=null){
if(cur.val<x)
smalls.add(cur.val);
else
bigs.add(cur.val);
cur=cur.next;
}
cur=head;
for(int i:smalls){
cur.val=i;
cur=cur.next;
}
for(int i:bigs){
cur.val=i;
cur=cur.next;
}
//ensure
return head;
}
}
【第2个代码】
public class Solution {
public ListNode partition(ListNode head, int x) {
//require
ListNode lessHead=new ListNode(-1),largeHead=new ListNode(-1);
ListNode cur=head,less=lessHead,large=largeHead;
//invariant
while(cur!=null){
if(cur.val<x){
less.next=cur;
less=less.next;
}else{
large.next=cur;
large=large.next;
}
cur=cur.next;
}
large.next=null;
less.next=largeHead.next;
//ensure
return lessHead.next;
}
}
参考
【LeetCode】Partition List 解题报告