给你单链表的头指针head和两个整数left和right,其中left<= right.请你反转从位置left到位置right的链表节点,返回反转后的链表
其实倒是不难 但是就是很多细节需要处理
这里left1表示第一个目标节点的前节点 right1是第一个目标节点 left2表示是第二个目标节点 right2是第二个目标节点的后继节点
- 然后首先进行的处理就是给原链表加一个哑元头节点,这样可以很好的避免比如第一个节点就开始翻转的情况等等,解决了很多的分类讨论问题
- 其次就是left1和right1确定的时候 for循环的终止条件是left-1 因为题目中给的left是从1开始计算的 而我们这边从0开始计算,并且找到的是第一个目标节点right1的前节点left1,left-1位置就是第一个目标节点right1 所以小于left-1找到的是left1表示第一个目标节点的前节点
- 但是!!!在找第二个目标节点的前节点left2时 for循环的终止条件是right 因为right-1这个位置就是第二个目标节点left1
- 还需要注意的就是在反转链表前将left1节点置空 left2节点置空
public class Solution024 {
public static void main(String[] args) {
ListNode l5 = new ListNode(5),
l4 = new ListNode(4,l5),
l3 = new ListNode(3,l4),
l2 = new ListNode(2,l3),
l1 = new ListNode(1,l2);
ListNode listNode = reverseBetween(l1, 2, 4);
System.out.println(listNode.toString());
}
public static ListNode reverseBetween(ListNode head, int left, int right){
//因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
ListNode dummy = new ListNode();
dummy.next=head;
ListNode left1 = dummy,left2 = dummy;
for (int i=0;i<left-1;i++){
left1=left1.next;
}
ListNode right1 = left1.next;
for (int i=0;i<right;i++){
left2=left2.next;
}
ListNode right2 = left2.next;
left1.next=null;
left2.next=null;
ListNode node = reverse(right1);
left1.next=node;
right1.next=right2;
return dummy.next;
}
public static ListNode reverse(ListNode node){
if (node==null || node.next==null) return node;
ListNode newHead = reverse(node.next);
node.next.next = node;
node.next=null;
return newHead;
}
}