题目
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
题目链接:https://leetcode-cn.com/problems/reverse-linked-list-ii
思路
我的想法是,像上一次做 k个一组反转链表的题目一样
- 先将 start(开始节点)跑到 m位置,然后记录下此时 prev(先前节点)
- 然后再让 end(结束反转位置)跑到 n位置
- 将 start参数传递进反转函数中,进行反转
- 将反转过程中故意断掉的节点重新接上
代码
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
// 先让链表跳到该位置的前面
ListNode prev = null;
ListNode start = head;
for(int i=0; i<m-1; i++){
prev = start;
start = start.next;
}
ListNode end = start;
// 再让 end循环到n处
for(int i=0; i<n-m; i++){
end = end.next;
}
if(end == null){
System.out.println(start.val);
// 说明需要全部反转
reverseNode(start);
return head;
}
// 现在可以反转 start和 end了
ListNode nextTemp = end.next;
end.next = null;
reverseNode(start);
if(prev == null){
head = end;
}else{
prev.next = end;
}
start.next = nextTemp;
return head;
}
public void reverseNode(ListNode head){
ListNode prev = null;
ListNode curr = head;
while(curr != null){
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
}
}
更加简洁的解题方法
public class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
while (m > 1) {
prev = prev.next;
m--;
n--;
}
head = prev.next;
while (n > 1) {
ListNode next = head.next;
head.next = head.next.next;
next.next = prev.next;
prev.next = next;
n--;
}
return dummy.next;
}
}
还可以使用递归的解法:链接