问题描述:
给你单链表的头指针 head
和两个整数 left
和 right
,其中 left <= right
。请你反转从位置 left
到位置 right
的链表节点,返回 反转后的链表 。
问题解法:
方法一:串针引线法
把链表分成三部分,使用reverseList(head)进行区间的反转,然后在进行三部分的拼接。如图:
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
for (int i = 0; i < left-1; i++) {
pre = pre.next;
}
ListNode leftNode = pre.next;
ListNode rightNode = leftNode;
for (int i = 0; i < right-left; i++) {
rightNode = rightNode.next;
}
ListNode succ = rightNode.next;
rightNode.next = null;
reverseList(leftNode);
pre.next = rightNode;
leftNode.next = succ;
return dummy.next;
}
public ListNode reverseList(ListNode head){
if(head == null || head.next == null){
return head;
}
ListNode cur = head;
ListNode res = null;
while(cur != null){
ListNode next = cur.next;
cur.next = res;
res = cur;
cur = next;
}
return res;
}
方法二:头插法
只遍历一遍链表,使节点插入到对应的位置,即pre节点后即可。
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
for (int i = 0; i < left-1; i++) {
pre = pre.next;
}
ListNode cur = pre.next;
for (int i = 0; i < right - left; i++) {
ListNode next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummy.next;
}