思路分析:
设置一个lessIndex索引,表示连续小于x值的最后一个的索引,初始值为null,想清楚含义至关重要。题目要保证原始的元素的相对顺序不变。遍历到小于x值得元素,将x值的节点放到lessIndex的后面,然后更新lessIndex以保持它的含义。总体思路是这样的,但还有一些细节问题,比如:第一个lessIndex如何处理;当lessIndex与当前节点相邻时,不能按照这两个节点不相邻的方式处理,如果这样处理的话,会删除一个节点,这是我们不想看到的,根据不同的情况做相应的逻辑处理。用一个简单的例子可以帮助我们更好的处理逻辑。
这是我在leetcode上通过的代码,时间复杂度O(n),空间复杂度O(1):
//leetcode 86. Partition List
public ListNode partition(ListNode head, int x) {
ListNode cur = head;
ListNode pre = null;
ListNode lessIndex = null; //连续小于x值的最后一个的索引;例如:1 <2 <3< x;lessIndex指向3这个节点
while(cur!=null){
if(cur.val<x&&cur!=head){
if(lessIndex!=null&&lessIndex.next!=cur){
ListNode cur_after = cur.next;
cur.next = lessIndex.next;
lessIndex.next = cur;
lessIndex = lessIndex.next;
pre.next = cur_after;
cur = cur_after;
}else if(lessIndex!=null&&lessIndex.next==cur){
lessIndex = lessIndex.next;
pre = cur;
cur = cur.next;
}else{
ListNode cur_after = cur.next;
lessIndex=cur;
lessIndex.next = head;
head = lessIndex;
pre.next = cur_after;
cur = cur_after;
}
}else if(cur.val<x&&cur==head){
lessIndex=head;
pre = cur;
cur = cur.next;
}else{
pre = cur;
cur = cur.next;
}
}
return head;
}
leetcode 328. Odd Even Linked List
这道题的思路和上一题简直是一模一样,就是把奇数索引的节点放在前面,而上一题是把小于x的值放在前面,稍微改动下代码提交leetcode就能过,然而效率只超过的20%的提交数,而上一题的效率大约超过70%的提交数。仔细想下,上一题考虑lessIndex与当前节点相邻时的问题,而这一题根本就不需要考虑,它们不可能相邻,因为奇数索引不可能相邻,可以稍加优化,相信性能会更好。
参考代码如下:
//leetcode 328. Partition List
public ListNode partition2(ListNode head) {
ListNode cur = head;
ListNode pre = null;
ListNode lessIndex = null; //连续奇数索引的最后一个的索引
int count=1;
while(cur!=null){
if(count%2==1&&cur!=head){
if(lessIndex!=null&&lessIndex.next!=cur){
ListNode cur_after = cur.next;
cur.next = lessIndex.next;
lessIndex.next = cur;
lessIndex = lessIndex.next;
pre.next = cur_after;
cur = cur_after;
}else if(lessIndex!=null&&lessIndex.next==cur){
lessIndex = lessIndex.next;
pre = cur;
cur = cur.next;
}else{
ListNode cur_after = cur.next;
lessIndex=cur;
lessIndex.next = head;
head = lessIndex;
pre.next = cur_after;
cur = cur_after;
}
}else if(count%2==1&&cur==head){
lessIndex=head;
pre = cur;
cur = cur.next;
}else{
pre = cur;
cur = cur.next;
}
++count;
}
return head;
}