Reorder List

Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes' values.

For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.

给定一个链表让我们重新排列它,例如以前的顺序为0-1-2-3-4,排列后的顺序为0-4-1-3-2。我们首先要找到中间的节点,用快慢指针,这个比较简单,不过值得注意的是节点是奇数和偶数的不同情况。找到中间节点后我们可以借助堆栈将后半部分的节点压栈,然后从头结点开始一个一个的处理,可以解决。堆栈实际上帮我们将链表的后半段反转了,如果我们不借助堆栈也可以解决,我们可以将链表从中间节点分为两段,将后半段反转,然后再将两个链表合为一个链表,这样就不需要借助堆栈,时间复杂度为O(n), 空间复杂度为O(1)。下面是两种方法的代码:
1,Using stack

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public void reorderList(ListNode head) {
Stack<ListNode> stack = new Stack<ListNode>();
if(head == null) return;
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}

if(fast != null){
slow = slow.next;
}
while(slow != null) {
stack.push(slow);
slow = slow.next;
}
while(!stack.isEmpty()){
ListNode top = stack.pop();
ListNode temp = head.next;
head.next = top;
top.next = temp;
head = temp;

}
head.next = null;
}
}


2,Without stack

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public void reorderList(ListNode head) {
if(head == null || head.next == null) return;
ListNode fast = head;
ListNode slow = head;
ListNode pre = null;
//get the middle node, and cut list into two sublists
while(fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode midNode = slow.next;
slow.next = null;

// reverse the latter part
ListNode newNode = reverseLatterPart(midNode);

//merge two sublists
while(newNode != null) {
ListNode tem = head.next;
head.next = newNode;
head = newNode;
newNode = tem;
}

}
private ListNode reverseLatterPart(ListNode head) {
ListNode prev = null;
ListNode tem = null;
while(head != null) {
tem = head.next;
head.next = prev;
prev = head;
head = tem;
}
return prev;
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值