1. 穿针引线法
注意:头结点会变化,最好使用一个虚拟头结点避免分类讨论
- 先找到需要反转的区间
- 切出链表反转处理
- 拼接
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
if(left == right){
return head;
}
ListNode vHead = new ListNode(-1);
vHead.next = head;
ListNode p = vHead;
while(left > 1){
left--;
p = p.next;
}
ListNode q = vHead;
while(right > 0){
right--;
q = q.next;
}
ListNode r = q.next;
q.next = null;
p.next = revers(p.next,r);
return vHead.next;
}
public ListNode revers(ListNode head,ListNode r){
ListNode cur = head.next;
ListNode pre = head;
head.next = r;
while(cur!= null){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}
2. 头插法
思路: 每次指针移动将next结点移到头部位置,依此实现反转效果
注意链表的连接顺序,pre和cur指针不动,移动next
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
if(left == right){
return head;
}
ListNode vHead = new ListNode(-1);
vHead.next = head;
ListNode pre = vHead;
while(left > 1){
left--;
pre = pre.next;
}
ListNode q = vHead;
while(right >= 0){
right--;
q = q.next;
}
ListNode next = pre.next.next;
ListNode cur = pre.next;
while(next != q){
cur.next = next.next;
next.next = pre.next;
pre.next = next;
next = cur.next;
}
return vHead.next;
}
}