将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转;
public ListNode reverseBetween(ListNode head, int m, int n) {
// 1 >> 2 >> 3 >> 4 >> 5 >> 6 >> 7 >> 8 假设反转 3~6
// 1 >> 2 >> 6 >> 5 >> 4 >> 3 >> 7 >> 8
/**
* 这个里面有几个关键点
* 找到元素2 到2之前的元素都不会发生变更 pre
* 找到元素7 到7之后的元素都不会发生变更 right
* 找到元素3 从该元素开始反转 start
* 找到元素6 从该元素结束反转 end
* start ~ end 之间的元素进行反转
* 如上图链表反转之后 2->6 即 pre.next - end ,3->7 即 start.next - right
*/
ListNode res = new ListNode(0);
res.next = head ;
ListNode pre = res;
for (int i = 0; i < m-1; i++) {
pre = pre.next ;
}
ListNode start = pre.next ;
ListNode end = start ;
for (int i = 0; i < n-m; i++) {
end = end.next ;
}
ListNode right = end.next ;
end.next = null ;
// 区间反转
reverseNode(start);
pre.next = end ;
start.next = right ;
return res.next ;
}
private void reverseNode(ListNode node) {
if(node == null || node.next ==null){
return;
}
Stack<ListNode> stack = new Stack<>();
while (node!=null){
stack.add(node);
node = node.next;
}
ListNode res = stack.pop();
while (!stack.isEmpty()){
res.next = stack.pop();
res = res.next ;
}
}
class ListNode {
int val;
ListNode next = null;
public ListNode(int val) {
this.val = val;
}
}