链表指定区间反转
1.头插法
思路:在反转的区间内,每次遍历到一个新的节点,都把它接入到反转起点(left位置)。
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(-1,head);
ListNode pre = dummy;
ListNode next = null;
for(int i=0;i<left-1;i++){
pre = pre.next;
}
ListNode cur = pre.next;
for(int i=0;i<right-left;i++){
next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummy.next;
}
2.穿针引线法
思路:将反转区间的前节点(pre)和后节点(succ)存起来,直到反转区间反转完成,再接入反转链表即可。
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(-1,head);
ListNode pre = dummy;
for(int i=0;i<left-1;i++){
pre = pre.next;
}
ListNode rightNode = pre;
for(int i=0;i<right-left+1;i++){
rightNode = rightNode.next;
}
ListNode succ = rightNode.next;
ListNode leftNode = pre.next;
rightNode.next = null;//防止成环
reverseLinkedList(leftNode);
pre.next = rightNode;//此时链表反转完成,左右节点位置互换
leftNode.next = succ;
return dummy.next;
}
private void reverseLinkedList(ListNode head) {//反转链表
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
}