题目地址:
https://www.lintcode.com/problem/reverse-linked-list-ii/description
给定一个链表,翻转其从第 m m m到 n n n位置的节点,包括两个端点。
基本思路是,先找到第 m − 1 m-1 m−1个节点,然后再找到第 n n n个节点,接着将第 m m m到 n n n位置的节点从链表中断开,将其翻转,再连到原链表中间即可。代码如下:
public class Solution {
/**
* @param head: ListNode head is the head of the linked list
* @param m: An integer
* @param n: An integer
* @return: The head of the reversed ListNode
*/
public ListNode reverseBetween(ListNode head, int m, int n) {
// write your code here
ListNode dummy = new ListNode(0);
dummy.next = head;
// prev表示第m - 1个节点,after表示第n + 1个节点
ListNode prev = dummy, after = null;
// first表示第m个节点,tail表示第n个节点
ListNode first = dummy, tail = null;
first = first.next;
for (int i = 0; i < m - 1; i++) {
first = first.next;
prev = prev.next;
}
after = first;
for (int i = 0; i < n - m; i++) {
after = after.next;
}
tail = after;
after = after.next;
// 将第n个节点和其后的节点断开
tail.next = null;
// 翻转第m到第n个节点,并连到第n - 1个节点后面
prev.next = reverse(first);
// 翻转后第n个节点就是原先的第m个节点,将其与原链表的第n + 1个节点连起来
first.next = after;
return dummy.next;
}
private ListNode reverse(ListNode head) {
ListNode res = null;
while (head != null) {
ListNode tmp = head.next;
head.next = res;
res = head;
head = tmp;
}
return res;
}
}
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。