题目:

Reverse a linked list from position m to n. Do it in-place and in one-pass.

For example:
Given 1->2->3->4->5->NULLm = 2 and n = 4,

return 1->4->3->2->5->NULL.

Note:
Given mn satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.

链接:  http://leetcode.com/problems/reverse-linked-list-ii/

题解:

把翻转部分隔离出来,记录这部分之前的节点和之后的节点。然后翻转这部分,再和之前记录的两个节点连接起来就可以了。

Time Complexity - O(n), Space Complexity - O(1)

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if(head == null || head.next == null || m == n)
return head;
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode preHeadToReverse = dummy, tailToReverse = dummy;
int count = 0; while(count < n) {
if(tailToReverse == null)
return dummy.next;
if(count < m - 1)
preHeadToReverse = preHeadToReverse.next;
tailToReverse = tailToReverse.next;
count++;
} ListNode headToReverse = preHeadToReverse.next, postTailToReverse = tailToReverse.next;
tailToReverse.next = null;
preHeadToReverse.next = reverse(headToReverse);
headToReverse.next = postTailToReverse;
return dummy.next;
} private ListNode reverse(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode dummy = new ListNode(-1); while(head != null) {
ListNode tmp = head.next;
head.next = dummy.next;
dummy.next = head;
head = tmp;
} return dummy.next;
}
}

这道题目应该和其他几道联合起来做,比如按照先后顺序完成以下几道题目

1) Reverse Linked List

2) Reverse Linked List II

3) Swap Node in Pairs

4) Swap Node in K-Gruo

二刷:

我们需要记录四个变量, pre, headToReverse,tailToReverse, postTail,然后当遍历时节点在headToReverse以及tailToReverse的时候我们反转。下面我写得比较麻烦,单独把reverse写成了一个函数,而切要先找到结尾点才能reverse,这样就多遍历了一遍反转区域,还需要好好改写。

Java:

Time Complexity - O(n), Space Complexity - O(1)

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null || head.next == null || m == n) {
return head;
}
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode preHeadToReverse = dummy, tailToReverse = dummy;
while (m > 1 || n > 0) {
if (m > 1) {
preHeadToReverse = preHeadToReverse.next;
m--;
}
if (n > 0) {
tailToReverse = tailToReverse.next;
n--;
}
}
ListNode headToReverse = preHeadToReverse.next, postTailToReverse = tailToReverse.next;
tailToReverse.next = null;
preHeadToReverse.next = reverse(headToReverse);
headToReverse.next = postTailToReverse;
return dummy.next;
} private ListNode reverse(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode dummy = new ListNode(-1);
ListNode tmp = new ListNode (-1);
while (head != null) {
tmp = head.next;
head.next = dummy.next;
dummy.next = head;
head = tmp;
}
return dummy.next;
}
}

下面直接one pass。 我们先设置fakeHead dummy, 让preHead = dummy, 找的过程中当m > 1的时候  preHeadToReverse = preHeadToReverse .next, 然后找到headToReverse = preHeadToReverse.next,也设置一个标记tail = headToReverse,最后用来添加连接反转前节点n的后一个节点postTail。

接下来我们先设置preHeadToReverse.next = null,在(n > 0以及headToReverse != null)的情况下, 我们利用reverse linkedlist的方法遍历这部分反转区域。遍历完毕以后的headToReverse就等于反转前节点n的下一个节点postTail, 这时候我们只需要将两部分连接起来,做一个  tail.next = headToReverse就可以了。还能再简化。

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null || head.next == null || m == n) {
return head;
}
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode preHeadToReverse = dummy;
while (m > 1) {
preHeadToReverse = preHeadToReverse.next;
m--;
n--;
}
ListNode headToReverse = preHeadToReverse.next;
ListNode tail = headToReverse, node = headToReverse;
preHeadToReverse.next = null;
while (n > 0 && headToReverse != null) {
node = headToReverse.next;
headToReverse.next = preHeadToReverse.next;
preHeadToReverse.next = headToReverse;
headToReverse = node;
n--;
}
tail.next = headToReverse;
return dummy.next;
}
}

三刷:

方法和二刷一样。

  1. 先找到m的前一个节点pre,这里要注意是在m > 1的条件下进行遍历
  2. 设置head = pre.next,用来进行遍历,  设置tail = head,因为翻转完毕以后这个head节点应该处于最后,所以我们设置这个tail用来连接n后面的节点们
  3. 设置tmp = head,也可以直接设置tmp为null,用来保存时head下一位置的节点
  4. 设置pre.next = null
  5. 在n > 0的情况下进行翻转,每次n--
  6. 最后连接tail和tmp,然后返回结果

Java:

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy; while (m > 1) {
pre = pre.next;
m--;
n--;
} head = pre.next;
ListNode tail = head;
ListNode tmp = head;
pre.next = null; while (n > 0) {
tmp = head.next;
head.next = pre.next;
pre.next = head;
head = tmp;
n--;
} tail.next = tmp;
return dummy.next;
}
}

Reference:

https://leetcode.com/discuss/10794/share-my-java-code

https://leetcode.com/discuss/25580/simple-java-solution-with-clear-explanation

https://leetcode.com/discuss/35440/240ms-java-solution

https://leetcode.com/discuss/72660/short-java-solution-for-reverse-linked-list-ii

92. Reverse Linked List II的更多相关文章

  1. 92. Reverse Linked List II【Medium】

    92. Reverse Linked List II[Medium] Reverse a linked list from position m to n. Do it in-place and in ...

  2. [LeetCode] 92. Reverse Linked List II 倒置链表之二

    Reverse a linked list from position m to n. Do it in one-pass. Note: 1 ≤ m ≤ n ≤ length of list. Exa ...

  3. [LeetCode] 92. Reverse Linked List II 反向链表II

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...

  4. 【LeetCode】92. Reverse Linked List II 解题报告(Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 递归 日期 题目地址:https://leet ...

  5. leetcode 92 Reverse Linked List II ----- java

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...

  6. LeetCode OJ 92. Reverse Linked List II

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...

  7. 【leetcode】92. Reverse Linked List II

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...

  8. 【一天一道LeetCode】#92. Reverse Linked List II

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Reverse ...

  9. LeetCode 92. Reverse Linked List II倒置链表2 C++

    Reverse a linked list from position m to n. Do it in one-pass. Note: 1 ≤ m ≤ n ≤ length of list. Exa ...

随机推荐

  1. linux file命令小记

    在linux中,所有东西都是文件:而且他并没有后缀名这一概念.Linux的扩展名没有太大的意义, file.tar.gz file.tgz file.tar.bz2 file.rar file.gz ...

  2. [转]WINDOW进程间数据通讯以及共享内存

    1.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效地进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换,就如同 ...

  3. shell命令行快速编辑命令

    ctrl r:命令行出现 reverse-i-search,输入字符将在输入历史中匹配命令 ctrl p:向前翻看历史 ctrl n:向后翻看历史 ctrl a:命令行首 ctrl e:命令行尾 ct ...

  4. 《SELinux安全上下文的管理(含图)》RedHat6.3——步骤详细、条理清晰

    1.为什么浏览器只识别/var/www/html下的文件? 2.为什么不识别别的目录下的index.html文件呢? 3.这里牵扯到身份证,先安装软件包. 4.打开selinux 5.建立一个新的目录 ...

  5. 【实习记】2014-08-19升级vim配置YouCompleteMe并debug的过程+qtcreator有语言包没法换语言

        做了个小项目,有空闲可以做点事了. 偶然查资料看见YouCompleteMe的鼎鼎大名. 演示demo <img src="http://i.imgur.com/0OP4ood ...

  6. Android SDK Manager国内无法更新的解决方案

    万里长城永不倒,千里黄河水滔滔.算了跑题了. 但还是要吐槽这下这个万里长城,感谢 方滨兴 叫兽 给我们净化了互联网,靠!什么&!@#¥ 此处略去一万字. 现在由于GWF,google基本和咱们 ...

  7. 【Qt】Qt环境搭建(Visual Studio)【转】

    简述 经常有人问我编写Qt程序时使用什么IDE,其实这个真的很难回答(各有所长),只能说看个人爱好了,因为我两个都用,而且两个都很喜欢(比较多情吧O(∩_∩)O~)! 下面将进行Qt Creator与 ...

  8. Oracle 执行计划说明

    生成SQL的执行计划是Oracle在对SQL做硬解析时的一个非常重要的步骤,它制定出一个方案告诉Oracle在执行这条SQL时以什么样的方式访问数据:索引还是全表扫描,是Hash Join还是Nest ...

  9. db2使用Java存储过程实现MD5函数

    1.数据库版本 2.Java脚本 import java.security.MessageDigest; import COM.ibm.db2.app.UDF; public class MD5UDF ...

  10. 四个基数任意次数组合相加得到一个数N,求所有可能组合

    #include <iostream> #include <vector> usingnamespace std; vector<int> vec; constin ...