示例 1:
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
法一:头插法(节点变位置)
private static ListNode reverseBetween2(ListNode head, int left, int right) {
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
for(int i = 0; i < left - 1; i++){
pre = pre.next;
}
ListNode cur = pre.next;
ListNode next;
for(int i = 0; i < right - left; i++){
next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummyNode.next;
}
法二:穿针引线法(反转部分的指针变方向,再拼接)
private static ListNode reverseBetween(ListNode nodeA, int left, int right) {
ListNode dummyNode = new ListNode(-1);
dummyNode.next = nodeA;
ListNode pre = dummyNode;
//要翻转起始位置的前一位(拼接的前端末)
for(int i = 0; i < left - 1; i++){
pre = pre.next;
}
//反转起始位置
ListNode leftNode = pre.next;
//反转终止位置
ListNode rightNode = pre;
for(int i = 0; i < right - left + 1; i++){
rightNode = rightNode.next;
}
//拼接的末端头
ListNode succ = rightNode.next;
//待反转部分末尾置空,以便反转,否则succ也将被反转
rightNode.next = null;
//反转中间部分
reverseList(leftNode);
pre.next = rightNode;
leftNode.next = succ;
return dummyNode.next;
}
public static ListNode reverseList(ListNode head){
ListNode pre = null;
ListNode cur = head;
while(cur != null){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}