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, 比其它方法快)

 1 public class Solution {
 2     public void reorderList(ListNode head) {
 3         if (head == null) return;
 4         ListNode dummy = new ListNode(-1);
 5         dummy.next = head;
 6         ListNode runner = dummy;
 7         ListNode walker = dummy;
 8         while (runner != null && runner.next != null) {
 9             runner = runner.next.next;
10             walker = walker.next;
11         }
12         ListNode head2 = walker.next;
13         walker.next = null;
14         head2 = reverse(head2);
15         runner = head2;
16         walker = head;
17         ListNode prev = dummy;
18         while (runner!=null && walker!=null) {
19             ListNode next = runner.next;
20             runner.next = walker.next;
21             walker.next = runner;
22             runner = next;
23             walker = walker.next.next;
24             prev = prev.next.next;
25         }
26         if (runner != null) {
27             prev.next = runner;
28         }
29     }
30
31     public ListNode reverse(ListNode header) {
32         if (header == null) return null;
33         ListNode dummy = new ListNode(-1);
34         dummy.next = header;
35         ListNode cur = header;
36         while (cur.next != null) {  //find the last non-null element of this list
37             cur = cur.next;
38         }
39         ListNode last = cur; // name the last non-null element as last
40         while (dummy.next != last) {
41             cur = dummy.next;
42             ListNode next = cur.next;
43             cur.next = last.next;
44             last.next = cur;
45             dummy.next = next;
46         }
47         return dummy.next;
48     }
49 }

第一遍的时候的代码:

 1 /**
 2  * Definition for singly-linked list.
 3  * class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) {
 7  *         val = x;
 8  *         next = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     public void reorderList(ListNode head) {
14         if (head == null || head.next == null) return;
15         ListNode dummy = new ListNode(-1);
16         dummy.next = head;
17         ListNode current = dummy;
18         ListNode runner = dummy;
19         while (runner.next != null && runner.next.next != null) {
20             current = current.next;
21             runner = runner.next.next;
22         }
23         ListNode half = current.next;
24         current.next = null;
25
26         /*reverse the second Linked List*/
27         if (runner.next != null) runner = runner.next; //make sure the runner pointer points to the end of the the second Linked List
28         ListNode dummy2 = new ListNode(-2);
29         dummy2.next = half;//create another dummy node whose next points to the head of the second Linked List
30         while (dummy2.next != runner) {
31             ListNode dnext = dummy2.next.next;
32             ListNode rnext = runner.next;
33             dummy2.next.next = rnext;
34             runner.next = dummy2.next;
35             dummy2.next = dnext;
36         }
37
38         /*merge the two Linked List together*/
39         ListNode header1 = dummy;
40         ListNode header2 = dummy2;
41         while (header1.next != null && header2.next != null) {
42             ListNode store = header1.next.next;
43             ListNode merge = new ListNode(header2.next.val);
44             header1.next.next = merge;
45             merge.next = store;
46             header1 = header1.next.next;
47             header2 = header2.next;
48         }
49         if (header2.next != null) {
50             header1.next = header2.next;
51         }
52     }
53 }

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

 1 private ListNode reverse(ListNode head)
 2 {
 3     ListNode pre = null;
 4     ListNode cur = head;
 5     while(cur!=null)
 6     {
 7         ListNode next = cur.next;
 8         cur.next = pre;
 9         pre = cur;
10         cur = next;
11     }
12     return pre;
13 }     

备用方法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     }

转载于:https://www.cnblogs.com/EdwardLiu/p/3960290.html

Leetcode: Reorder List Summary: Reverse a LinkedList相关推荐

  1. LeetCode 206. 反转链表 Reverse Linked List

    5-1 链表,在节点间穿针引线 Reverse Linked List 题目: LeetCode 206. 反转链表 反转一个单链表. 示例: 输入: 1->2->3->4-> ...

  2. LeetCode 206. 反转链表(Reverse Linked List) 16

    206. 反转链表 206. Reverse Linked List 题目描述 反转一个单链表. 每日一算法2019/5/19Day 16LeetCode206. Reverse Linked Lis ...

  3. LeetCode - Reorder List

    Reorder List 2014.1.13 22:07 Given a singly linked list L: L0→L1→-→Ln-1→Ln, reorder it to: L0→Ln→L1→ ...

  4. LeetCode.917-只反转字母(Reverse Only Letters)

    这是悦乐书的第353次更新,第378篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第215题(顺位题号是917).给定一个字符串S,返回"反向"字符串 ...

  5. [Leetcode] 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 th ...

  6. LeetCode 7. 整数反转 Reverse Integer 官网答案的条件判定的一点思考

    关于solution中的公式不知道是否清楚,在刚开始看的时候认为条件之一应当是rev<(Integer.min-pop)/10这个条件,因为rev*10+pop>Integer.min时才 ...

  7. Leetcode: Reorder List

    FROM 思路 1. 将后半段截取下来再倒序, 插入到前半段, 时间复杂度为 o(n) 代码 #include <iostream> using namespace std;struct ...

  8. LeetCode Reorder List

    题意:给出一个链表,重新排列链表,形式为第一个-->倒数第一个->第二个->倒数第二个 思路:将数组分成两半,然后将后半部反转,再拼接 代码发下: class Solution {p ...

  9. leetcode解题笔记-Summary Ranges

    题目要求: 给定一个排序好的int数组,按照间隔输出字符串 个人解法: 1.设一个临时变量,用来存->后面的值, 2. 遍历一次数组,注意要判断是否到最后一位. 代码: public stati ...

  10. LeetCode之Reverse Integer

    1.题目 Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 cli ...

最新文章

  1. nagios 监控NFS
  2. qt android 对话框,Qt自定义Dialog
  3. android 图片放大缩小_贴在手机上的显微镜,轻松放大400倍,化身“蚁人”玩转微观世界...
  4. for循环c语言流水灯,巧用数组与for循环为流水灯程序瘦身
  5. PHP、mysql面试题 (附答案+实现代码)
  6. Golang配置文件解析-oozgconf
  7. appinventor广州服务器网页,app inventor服务器
  8. python基础语法手册-Python学习手册(第4版)pdf
  9. 001 Python中的变量和字符串
  10. php 三大魔术方法,PHP魔术方法
  11. c语言图书管理系统简单代码,C语言图书管理系统代码
  12. 软件测试用例设计规范
  13. matlab中表示矩阵的转置,注意Matlab中的矩阵转置(转)
  14. 3dmax如何导入ies灯
  15. Android zip文件压缩与解压
  16. 个人笔记——消除无用符号·消除空产生式·消除单一产生式·消除左递归
  17. 华硕A8SE系列安装windows XP +驱动安装
  18. C++ 一文解决 数据库ODB 安装/调试/使用的问题
  19. excel oracle 可为空,类似excel定位功能用不为空值填充为空列,用sql怎么实现
  20. 决策树和 K 近邻分类

热门文章

  1. 康托展开逆展开算法笔记
  2. unity3d所要知道的基础知识体系大纲,可以对照着学习
  3. Mac 显示和隐藏文件
  4. 本地上支持apache多站点访问
  5. Form Follows Function – 绚丽的 HTML5 互动体验网站
  6. Delphi运行期错误
  7. Oracle 10g OCP 官方培训
  8. AMD:40年三个关键词
  9. python类代码编写细节
  10. 线程(进程线程的比较)