给你单链表的头指针 head 和两个整数 left 和 right , 其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
// 示例 1:
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
思路:
首先定义一个哨兵节点作为参数链表的头结点,这样在返回的时候就可以直接返回头结点的next
首先把链表分为两部分,一部分是要反转的部分,另一部分就是剩下的。首先找到左节点的前一个节点。使用一个指针标记此节点。再遍历链表找到右边的节点。然后截断链表,再用一个函数将截取出来的链表进行反转。
或者直接在遍历到左边节点的时候,就将左节点到右节点的链表进行反转。最后再改变指针指向
代码实现:
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode();
dummy.next = head;
ListNode pre = dummy;
for(int i = 0; i < left -1; i++){
pre = pre.next;
}
ListNode rightNode = pre.next;
ListNode leftNode = pre;
for(int i = 0; i < right - left +1; i++ ){
leftNode = leftNode.next;
}
ListNode curr = leftNode.next;
pre.next = null;
leftNode.next = null;
reverse(rightNode);
pre.next = leftNode;
rightNode.next = curr;
return dummy.next;
}
public ListNode reverse(ListNode head){
ListNode pre = null;
ListNode cur = head;
while(cur != null){
ListNode nextNode = cur.next;
cur.next = pre;
pre = cur;
cur = nextNode;
}
return pre;
}
直接边遍历边反转
//原地反转
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
//遍历到左边的节点的前一个节点
for(int i = 1; i < left; i++){
pre = pre.next;
}
//此时pre指针指向的是左边的节点的前一个节点
//从现在开始,该节点的下一个节点一直到右边的节点,都需要180度旋转。
ListNode prev = null; //定义一个指针首先指向空
ListNode cur = pre.next; //现在这个指针指向左边的节点
for(int j = 0; j <= right - left; j++){ //左边节点到右边节点一直交换位置
ListNode nextNode = cur.next; //接收下一个节点
cur.next = prev; //第一个节点的next指针指向空
prev = cur;
cur = nextNode;
}
//修改left处和right处的指针指向
pre.next.next = cur;
pre.next = prev;
return dummy.next;