题目:

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. 笔试面试题-小米Git

    题目描述: git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常 ...

  2. 翻转单词顺序VS左旋转字符串

    题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.句子中单词以空格符隔开.为简单起见,标点符号和普通字母一样处理.例如输入“I am a student.”,则输出“student ...

  3. 0-1背包问题与N皇后问题的纠结

    昨日同学要我帮他看一道算法,如下: 是不是乍一看是“0-1背包”问题呀,我也这么想,于是就这么兴致勃勃的开始用这个想法去思考怎么算.但是算法也忘得差不多,回去赶紧补补,也趁着这次机会好好复习一下算法, ...

  4. 更新Android SDK 访问谷歌等无需代理方法

    最近要做ANDROID,本来是想通过找镜像网址下载,发现公司网络屏蔽了,后来网络上搜索一圈,发现如下方法 1)更改HOST 2)使用代理 使用代理在公司的环境中属于违规操作,因此不能使用 只剩更改HO ...

  5. PHP 类的静态变量索引

    直接上代码 <?php class example{ public static $pa; public $pb; public function __construct(){ $this-&g ...

  6. Ubuntu 16.04配置OpenCV 3.1.0 for Java

    我们都知道,OpenCV是基于C++的开源计算机视觉库,但是从2.4.4版本开始提供了Java绑定,也就是说,我们也可以使用Java来开发基于OpenCV的计算机视觉应用.目前,最新的版本是3.1.0 ...

  7. RestFul && HATEOAS && Spring-Data-Rest介绍

    1.什么是RestFul 经常上网的同学会发现,现代软件的一个重要趋势就是互联网化,几乎没有一款软件是纯粹的单机版了.通常的情况下,软件管理着服务器的资源以及这些资源的状态变化,用户通过在浏览器输入h ...

  8. c# 两个数组比较,将重复部分去掉,返回不重复部分

    List<string> Ashuzu = new List<string>(); Ashuzu.Add("); Ashuzu.Add("); List&l ...

  9. UserControl eventhander 注册问题

    1. 如果主页面调用UserControl来画界面 2. UserControl局部变化需要通过事件通知主页面,通过UserControl定义EventHandler,主界面注册UserControl ...

  10. tomcat源码解读(2)–容器责任链模式的实现

    责任链模式:责任链模式可以用在这样的场景,当一个request过来的时候,需要对这个request做一系列的加工,使用责任链模式可以使每个加工组件化,减少耦合.也可以使用在当一个request过来的时 ...