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)。

 class Solution {
public void reorderList(ListNode head) {
if (head == null) return;
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode p1 = dummy, p2 = dummy;
while (p2 != null && p2.next != null) {
p2 = p2.next.next;
p1 = p1.next;
}
ListNode head2 = p1.next;
p1.next = null;
ListNode head2New = reverse(head2);
merge(head, head2New);
} public ListNode reverse(ListNode head) {
if (head == null) return null;
ListNode p1 = head;
ListNode p2 = head.next;
while (p2 != null) {
ListNode next = p2.next;
p2.next = p1;
p1 = p2;
p2 = next;
}
head.next = null;
return p1;
} public ListNode merge(ListNode l1, ListNode l2) {
if (l2 == null) return l1;
int counter = 0;
ListNode pre = new ListNode(-1);
ListNode cur = pre;
while (l1 != null && l2 != null) {
if (counter % 2 == 0) {
cur.next = l1;
l1 = l1.next;
}
else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
counter ++;
}
cur.next = l1 != null ? l1 : l2;
return pre.next;
}
}

最新文章

  1. 让 select 的 option 标签支持事件监听(如复制操作)
  2. Visual Studio 2015 Bowser Link的功能不停的向服务端发送请求
  3. 最佳 Linux 发行版汇总
  4. CF464A (模拟)
  5. PHP基础之 错误处理 及 异常处理
  6. event对象的属性
  7. Know How To Use Check Box Mapping Of Other Values Property In Oracle Forms
  8. Java中print、printf、println
  9. 多进程和atexit清理函数
  10. python 列表推导的注意点
  11. html,shtml和htm的区别
  12. Java 日期与字符串的转换
  13. Windows下如何建立以"."开头的文件夹
  14. 谈谈数据库中MyISAM与InnoDB区别 针对业务类型选择合适的表
  15. java 1.8 动态代理源码分析
  16. Android 开发 获取Android设备的屏幕高宽
  17. soa 和微服务的区别
  18. vc++基础班[23]---文件夹的基本操作
  19. [C#.net]ListBox对Item进行重绘,设置背景色和前景色
  20. qq浏览器默认字体设置

热门文章

  1. 部署OpenStack问题汇总(六)-- OpenStack入门需要知道的概念
  2. 墨菲定律:当你觉得一个地方可能有bug,那么这个地方就会有bug----顺带了解下Tomcat那少有人注意的localhost.log
  3. [Sdoi2016]齿轮
  4. 编译安装的gitlab8.x如何修改时区设置
  5. mysql的启动脚本mysql.server及示例配置文件
  6. dos 磁盘操作系统
  7. NEFU 117 - 素数个数的位数 - [简单数学题]
  8. js-之NaN和isNaN
  9. HTML 标签大全及属性
  10. 线性参照,M值的相关测试