Leetcode面试经典150题-92.反转链表II
解法都在代码里,不懂就留言或者私信
比反转链表I略微难一点点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
/**反转链表1的难度升级版,注意处理边界条件 */
public ListNode reverseBetween(ListNode head, int left, int right) {
/**根据题目的设定,left一定小于等于right并且在有效范围内
所以链表只有一个节点的时候肯定就是left==right==1,这种也包含在我们的if内 */
if(left == right) {
return head;
}
/**寻找反转区间的前置节点和后驱节点*/
ListNode rangePre = null;
ListNode rangePost = head;
ListNode cur = head;
while(left> 1) {
rangePost = cur.next;
left --;
right --;
rangePre = cur;
cur = rangePost;
}
/**这里的rangePre是我们要反转的区间的前一个节点,继续寻找后继节点*/
while(right > 1) {
rangePost = cur.next;
right --;
cur = rangePost;
}
ListNode rangeStart = head;
/**出循环的时候rangPost就是整个区间的最后一个节点,不管前驱还是后继,都是有可能为空的,连接的时候要注意判断 */
if(rangePre != null) {
/**如果rangePre是null,那rangeStart就是head */
rangeStart = rangePre.next;
rangePre.next = null;
}
/**拿到当前区间后面的第一个节点*/
ListNode rangeNext = rangePost.next;
/**断开和后面的连接 */
rangePost.next = null;
ListNode newRangeHead = reverse(rangeStart);
/**如果rangePre不是null,连接新的头*/
if(rangePre != null) {
rangePre.next = newRangeHead;
}
rangeStart.next = rangeNext;
return rangePre != null? head : newRangeHead;
}
/**经典的反转链表 */
public ListNode reverse(ListNode head) {
ListNode pre = null;
ListNode next = null;
ListNode cur = head;
while(cur != null) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}