import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param left int整型
* @param right int整型
* @return ListNode类
*/
public ListNode reverseBetween (ListNode head, int left, int right) {
// write code here
if (head == null || head.next == null || left == right) return head;
ListNode hair = new ListNode(0), cur = hair;
hair.next = head;
for (int i = 0; i < left - 1; i++) cur = cur.next;
cur.next = reverseK(cur.next, right - left + 1);
return hair.next;
}
private ListNode reverseK(ListNode head, int k) {
ListNode p = null, cur = head, next;
while (k-- > 0) {
next = cur.next;
cur.next = p;
p = cur;
cur = next;
}
head.next = cur;
return p;
}
}
- 单向链表 K个一组翻转的变种题,首先可以先写一个 reverseK 方法
- 定义一个虚拟节点 p、一个用于遍历的指针 cur、以及用于记录下一个遍历的 next
- 循环翻转 k 次,每次先记录 next,然后 cur 指向的节点翻转 即 cur.next = p;
- 然后 p 先后走,cur 向后走
- 最后循环出来时,p就是翻转之后的头节点,同时注意将head与cur连接上
- 回到区间翻转 reverseBetween 方法中
- 首先做一些边界值判断,若链表为null、或者只有一个节点、或者翻转元素只有一个(即 left==right),则不需要翻转,直接返回
- 然后就是老套路,定义一个虚拟头节点 hair,并指向 head;定义一个遍历的指针 cur,指向 hair
- 循环 left-1 次,找到翻转左区间的前一个节点 cur
- 调用 reverseK 方法,并将返回值与cur对接上
- 最后返回 hair.next 即为区间翻转后的链表的结果