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}.

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/

【题意】

给定一个链表,把最后一个结点插入到第1个结点后,倒数第二个结点插入到第2个结点后,倒数第三个结点插入到第3个结点后,以此类推……

【思路】

由题意知。后面 (n-1)/2 个结点须要分别插入到前面 (n-1)/2 个结点后。

那么先把链表分为两段。前面 n-(n-1)/2 个结点为被插入链表,和后面 (n-1)/2 个结点为插入链表。

在插入之前,需先把插入链表逆序。即第n个结点->第n-1个结点->...

【Java代码】

public class Solution {
public void reorderList(ListNode head) {
ListNode node = head;
int cnt = 0;
while (node != null) {
cnt++;
node = node.next;
} if (cnt < 3) return;//3个以下的结点不须要移动 int k = (cnt - 1) / 2;//须要移动的后k个结点
int i = 1;
node = head;
while (i++ < cnt - k) {
node = node.next;
}
ListNode begin = node.next;//用begin表示须要移动的后k个结点的開始
node.next = null;//把不须要移动的部分结尾设为null //把须要移动的k个结点逆序
ListNode pre = begin;
ListNode cur = begin.next;
begin.next = null;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre; begin = cur;
pre = cur;
cur = next;
} ListNode node1 = head;
ListNode node2 = begin;
while (node1 != null && node2 != null) {
pre = node1;
cur = node2; node1 = node1.next;//这两行一定要放在以下两行之前。由于pre和node1指向同一个结点,以下操作会改变node1的next;cur和node2同理
node2 = node2.next; cur.next = pre.next;//这两行代码是把cur插入到pre后
pre.next = cur;
}
}
}

【感受】

代码写起来超恶心,写着写着就混乱了。一会儿就不知道next指的是哪个结点了。

【升级版】

先用快慢指针找到链表的中点。然后翻转链表后半部分,再和前半部分组合。

须要注意的是把链表分成两半时,前半段的尾节点要置为NULL,翻转链表时也要把尾节点置为NULL。

public class Solution {
public void reorderList(ListNode head) {
if (head == null || head.next == null) return; //把整个链表划分成2个等长的子链表。假设原链表长度为奇数。那么第一个子链表的长度多1
ListNode slow = head, fast = head;
while (fast.next != null) {
fast = fast.next;
if (fast.next != null) fast = fast.next;
else break;
slow = slow.next;
} ListNode head1 = head, head2 = slow.next;
slow.next = null; //翻转第二个子链表
ListNode cur = head2, post = cur.next;
cur.next = null;
while (post != null) {
ListNode tmp = post.next;
post.next = cur;
cur = post;
post = tmp;
}
head2 = cur; //将两个子链表合并
ListNode node1 = head1, node2 = head2;
while (node2 != null) {
ListNode tmp1 = node1.next;
ListNode tmp2 = node2.next;
node1.next = node2;
node2.next = tmp1;
node1 = tmp1;
node2 = tmp2;
}
}
}

【LeetCode】Reorder List 解题报告的更多相关文章

  1. 【LeetCode】143. Reorder List 解题报告(Python)

    [LeetCode]143. Reorder List 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

  2. LeetCode: Combination Sum 解题报告

    Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Questi ...

  3. 【LeetCode】Permutations 解题报告

    全排列问题.经常使用的排列生成算法有序数法.字典序法.换位法(Johnson(Johnson-Trotter).轮转法以及Shift cursor cursor* (Gao & Wang)法. ...

  4. LeetCode - Course Schedule 解题报告

    以前从来没有写过解题报告,只是看到大肥羊河delta写过不少.最近想把写博客的节奏给带起来,所以就挑一个比较容易的题目练练手. 原题链接 https://leetcode.com/problems/c ...

  5. LeetCode: Sort Colors 解题报告

    Sort ColorsGiven an array with n objects colored red, white or blue, sort them so that objects of th ...

  6. LeetCode: Permutation Sequence 解题报告

    Permutation Sequence https://oj.leetcode.com/problems/permutation-sequence/ The set [1,2,3,…,n] cont ...

  7. Leetcode:Interleaving String 解题报告

    Interleaving StringGiven s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For ...

  8. Leetcode:Scramble String 解题报告

    Scramble String Given a string s1, we may represent it as a binary tree by partitioning it to two no ...

  9. LeetCode: Gas Station 解题报告

    Gas Station There are N gas stations along a circular route, where the amount of gas at station i is ...

随机推荐

  1. ASP.NET - 匹配标签中的内容

    string str = @"<td>Csdn</td>\r\n<td>V1.0</td>\r\n<td>2014-10-23&l ...

  2. JVM性能监控与优化笔记(CPU)

    基础 对于CPU层面的监控主要以下几个点: 是否系统态CPU的占用率高 CPU运行队列中待运行的任务数 是否CPU停滞多,每时钟指令数(IPC)少(高级点,对于计算密集型的应用需要关注) 系统态CPU ...

  3. 服务确定撤销/删除/关闭 (ml81n)

    FUNCTION zrfc_mm006. *"---------------------------------------------------------------------- * ...

  4. Eclipse用法和技巧二:自动生成Main方法1

    刚开始编写java小程序,基本都要用到main方法.后期开发大一点的程序,也可以用main方法进行单元测试.总是编写main方法,感觉太无聊了,幸好Eclipse可以帮我们自动生成main方法.见图: ...

  5. 六款常用的linux C/C++ IDE

    摘要: 一.AnjutaAnjuta是一个多语言的IDE,它最大的特色是灵活,同时打开多个文件,内嵌代码级的调试器(调用gdb),应用程序向导(Application wizards)可以方便的帮助你 ...

  6. .bash_profile与.bashrc和.profile的区分概念

    在Linux系统中配置环境变量相关的文件主要有如下几个,很容易弄混的,这儿简单区分下: /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.并从/etc/p ...

  7. Eclipse使用总结

    Eclipse使用总结 1.Eclipse中出现无法找到Maven包     症状:出现org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER, 且出现无法找 ...

  8. 发掘ListBox的潜力(二):鼠标拖放插入点提示

    鼠标拖放插入点提示 鼠标拖放是Windows常见的操作,比如拷贝文件就可用拖放方式进行.在我们编写的应用程序中,有时为了方便用户操作需要支持鼠标拖放.对于大部分的VCL控件只要鼠标将DragMode设 ...

  9. 微信支付[v3]

    原文:微信支付[v3] V2升级V3 顺便记录一下 ,文档: http://pay.weixin.qq.com/wiki/doc/api/index.html !!! 支付授权目录与测试人的微信帐号白 ...

  10. 关于wind7重新安装系统后,连接mysql的问题

    系统重装对于我们来说,可以说是家常便饭了.但重装系统之后 ,又要装很多的应用软件是会很烦的.特别是重装一些数据库软件,时间长不说,搞不好数据丢失了会让人抓狂. 今天我简单介绍一个不用重装mysql的方 ...