给定一个单链表 L:L0→L1→…→Ln-1→Ln , 将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→… 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例1: 给定链表 1->2->3->4, 重新排列为 1->4->2->3. 示例 2: 给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.
public static class ListNode {
int val
;
ListNode next
;
ListNode(int val
) {
this.val
= val
;
}
ListNode(int val
, ListNode next
){
this.val
= val
;
this.next
= next
;
}
}
solution1:
public void reorderList1(ListNode head
) {
if (head
== null
|| head
.next
== null
|| head
.next
.next
== null
) {
return;
}
List
<ListNode> list
= new ArrayList<>();
ListNode cur
= head
;
while (cur
!= null
) {
list
.add(cur
);
cur
= cur
.next
;
}
int i
= 0, j
= list
.size() - 1;
while (i
< j
) {
list
.get(i
).next
= list
.get(j
);
i
++;
list
.get(j
).next
= list
.get(i
);
j
--;
}
list
.get(i
).next
= null
;
}
执行结果: 执行用时:4 ms, 在所有 Java 提交中击败了28.22%的用户 内存消耗:40.6 MB, 在所有 Java 提交中击败了99.42%的用户
时间复杂度:O(n) 空间复杂度:O(n),List开销
solution2:
public void reorderList2(ListNode head
) {
if (head
== null
|| head
.next
== null
|| head
.next
.next
== null
) {
return;
}
ListNode slow
= head
;
ListNode fast
= head
;
while(fast
.next
!= null
&& fast
.next
.next
!= null
){
slow
= slow
.next
;
fast
= fast
.next
.next
;
}
ListNode secondHead
= slow
.next
;
secondHead
= reverseList(secondHead
);
while (secondHead
!= null
){
ListNode next
= secondHead
.next
;
secondHead
.next
= head
.next
;
head
.next
= secondHead
;
head
= secondHead
.next
;
secondHead
= next
;
}
head
.next
= null
;
}
public ListNode
reverseList(ListNode head
){
if (head
== null
) {
return null
;
}
if (head
.next
== null
) {
return head
;
}
ListNode pre
= null
;
while (head
!= null
) {
ListNode next
= head
.next
;
head
.next
= pre
;
pre
= head
;
head
= next
;
}
return pre
;
}
执行结果: 执行用时:1 ms, 在所有 Java 提交中击败了100.00%的用户 内存消耗:41.2 MB, 在所有 Java 提交中击败了88.05%的用户
时间复杂度:O(n) 空间复杂度:O(1)