您的位置:首页 > 其它

Leetcode: Reorder List && Summary: Reverse a LinkedList

2014-09-07 12:07 281 查看
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}.


这是一道比较综合的链表操作的题目,要按照题目要求给链表重新连接成要求的结果。其实理清思路也比较简单,分三步完成:(1)将链表切成两半,也就是找到中点,然后截成两条链表;(2)将后面一条链表进行reverse操作,就是反转过来;(3)将两条链表按顺序依次merge起来。

这几个操作都是我们曾经接触过的操作了,第一步找中点就是用runner technique方法,一个两倍速跑,一个一倍速跑,知道快的碰到链表尾部,慢的就正好停在中点了。第二步是比较常见的reverse操作,在Reverse Nodes in k-Group也有用到了,一般就是一个个的翻转过来即可。第三步是一个merge操作,做法类似于Sort List中的merge

接下来看看时间复杂度,第一步扫描链表一遍,是O(n),第二步对半条链表做一次反转,也是O(n),第三部对两条半链表进行合并,也是一遍O(n)。所以总的时间复杂度还是O(n),由于过程中没有用到额外空间,所以空间复杂度O(1)。

第三遍代码(reverse LinkedList用的是最终默认方法)(实测328ms, 比其它方法快)

public class Solution {
public void reorderList(ListNode head) {
if (head == null) return;
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode runner = dummy;
ListNode walker = dummy;
while (runner != null && runner.next != null) {
runner = runner.next.next;
walker = walker.next;
}
ListNode head2 = walker.next;
walker.next = null;
head2 = reverse(head2);
runner = head2;
walker = head;
ListNode prev = dummy;
while (runner!=null && walker!=null) {
ListNode next = runner.next;
runner.next = walker.next;
walker.next = runner;
runner = next;
walker = walker.next.next;
prev = prev.next.next;
}
if (runner != null) {
prev.next = runner;
}
}

public ListNode reverse(ListNode header) {
if (header == null) return null;
ListNode dummy = new ListNode(-1);
dummy.next = header;
ListNode cur = header;
while (cur.next != null) {  //find the last non-null element of this list
cur = cur.next;
}
ListNode last = cur; // name the last non-null element as last
while (dummy.next != last) {
cur = dummy.next;
ListNode next = cur.next;
cur.next = last.next;
last.next = cur;
dummy.next = next;
}
return dummy.next;
}
}


第一遍的时候的代码:

/**
* Definition for singly-linked list.
* class ListNode {
*     int val;
*     ListNode next;
*     ListNode(int x) {
*         val = x;
*         next = null;
*     }
* }
*/
public class Solution {
public void reorderList(ListNode head) {
if (head == null || head.next == null) return;
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode current = dummy;
ListNode runner = dummy;
while (runner.next != null && runner.next.next != null) {
current = current.next;
runner = runner.next.next;
}
ListNode half = current.next;
current.next = null;

/*reverse the second Linked List*/
if (runner.next != null) runner = runner.next; //make sure the runner pointer points to the end of the the second Linked List
ListNode dummy2 = new ListNode(-2);
dummy2.next = half;//create another dummy node whose next points to the head of the second Linked List
while (dummy2.next != runner) {
ListNode dnext = dummy2.next.next;
ListNode rnext = runner.next;
dummy2.next.next = rnext;
runner.next = dummy2.next;
dummy2.next = dnext;
}

/*merge the two Linked List together*/
ListNode header1 = dummy;
ListNode header2 = dummy2;
while (header1.next != null && header2.next != null) {
ListNode store = header1.next.next;
ListNode merge = new ListNode(header2.next.val);
header1.next.next = merge;
merge.next = store;
header1 = header1.next.next;
header2 = header2.next;
}
if (header2.next != null) {
header1.next = header2.next;
}
}
}


其他一些备用的reverse一个LinkedList的方法: 这些方法都很巧,但是不太好想,不太好写,我还是用默认方法吧

private ListNode reverse(ListNode head)
{
ListNode pre = null;
ListNode cur = head;
while(cur!=null)
{
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}


备用方法2:

31     public ListNode reverse(ListNode header) {
32         if (header==null) return null;
33         ListNode prev = new ListNode(-1);
34         prev.next = header;
35         ListNode cur = prev;
36         ListNode node1 = header;
37         ListNode node2 = header.next;
38         ListNode end = header;
39         while (node2 != null) {
40             ListNode next = node2.next;
41             cur.next = node2;
42             node2.next = node1;
43             node1 = node2;
44             node2 = next;
45         }
46         end.next = null;
47         return prev.next;
48     }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: