原题链接: https://leetcode.com/problems/reverse-linked-list-ii/
1. 题目介绍
Reverse a linked list from position m to n. Do it in one-pass.
Note: 1 ≤ m ≤ n ≤ length of list.
给出一个链表,以及数字 m、n。反转 [m , n ] 部分的链表。使用一次循环。
1 ≤ m ≤ n ≤ length length 是链表的长度
Example:
Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL
2. 解题思路
这个题是 206. Reverse Linked List 的加强版。206. Reverse Linked List 是反转整个链表,而本题是反转[ m , n ]那一段的节点。
注:下面的方法参考了 https://www.cnblogs.com/grandyang/p/4306611.html 的解法
我们需要设置两个指针,一个指针是pre ,指向第 m-1 个节点;一个指针是 cur ,指向第 m 个节点。
这个方法的主要思路是,依次把 cur 后面的节点放到第 m-1 个节点的后面。
-
首先把pre 指向第 m-1 个节点;cur,指向第 m 个节点,assist是最前面的辅助节点
-
然后依次将cur后面的第一个节点移动到pre后面,cur继续指向后面的第二个节点。这个步骤要重复 n-m 次。
-
之后直接返回 assist.next 就是正确的结果了。
实现代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if(head == null || m == n || head.next == null){
return head;
}
ListNode assist = new ListNode(0);
assist.next = head;
//让 pre 指向第 m-1 个节点,cur指向第 m 个节点
ListNode pre = assist;
for(int i = 0 ; i < m-1 ; i++){
pre = pre.next;
}
ListNode cur = pre.next;
//把 cur 后面的节点依次放到pre后面
for(int i = 1; i <= n-m; i++){
ListNode temp = cur.next;
cur.next = temp.next;
temp.next = pre.next;
pre.next = temp;
}
return assist.next;
}
}