LeetCode 92. Reverse Linked List II
2020-06-03 20:51:12 # leetcode # core problems

Problem

LeetCode 92. Reverse Linked List II

1. 题目简述

给出一个链表,和两个正整数m、n(1 <= m <= n <= length),翻转该链表的第m和n之间的元素。例如:

Example:

Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL

2. 算法思路

经典题目的难度加大的版本,难度在于我们需要找到起始位置和终止位置,基本思路如下:

  1. 首先找到第m个元素ptr,以及它前面的那个元素pre,pre有可能为null;
  2. 定义tail = ptr,因为翻转后,第m个元素就是翻转部分链表的结尾;
  3. 定义con = pre,这个con是用来记录当前pre是否为null的,如果不为null值,就将con和反转后的表头相连,,为null就直接返回反转后的表头;
  4. 定义tail = ptr,因为当前未翻转部分的表头ptr其实是反转后的末尾,记录一下,因为后面while循环后ptr就不在翻转列表里了,需要重新连一下。
  5. while循环,记录post元素,将ptr的next指向pre,然后更改ptr和pre(这里有一个注意事项,就是翻转第一个元素的时候可能有人会觉得不合理,其实这只是暂存,while循环后面会修正的)。
  6. 修正tail的指向;
  7. 判断连接处con是否为空,如果不为空则连接,为空则不连接。

for循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (m == n) {
return head;
}

ListNode ptr = head, pre = null;
while (m > 1) {
pre = ptr;
ptr = ptr.next;
m--;
n--;
}

ListNode con = pre, tail = ptr;
while (n > 0) {
ListNode post = ptr.next;
// 注意,对于第一个翻转的元素,这里只是暂存!!!后面ptr会变,这里其实是tail
ptr.next = pre;
pre = ptr;
ptr = post;
n--;
}

tail.next = ptr;
// while循环结束时,ptr处于第n+1个元素,pre是原本的第n个元素
if (con != null) {
con.next = pre;
} else {
return pre;
}

return head;
}
}