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 m int整型 * @param n int整型 * @return ListNode类 */ public ListNode reverseBetween (ListNode head, int m, int n) { // write code here // 算法时间复杂度O(N),额外空间复杂度O(1) // 1.先定义两个指针start和end,分别指向前方的m位置和后方的n位置 ListNode start = null; ListNode end = null; // 2.记录start指针的上一个结点allPre,end指针的下一个结点allPost ListNode allPre = head; // 先把allPre指向head这个整个链表的起点,随着查找m可以往后移动head ListNode allPost = null; // 准备找到m和n位置对应的start和end,以及对应的allPre和allPost ListNode cur = head; for (int i = 1; cur != null; cur = cur.next, i++) { if (i == m) { start = cur; } if (i == n) { end = cur; allPost = end.next; break; } // 只有在i>1(让allPre落后一位)且i<m(还没找到start)时更新allPre if (i > 1 && i < m) { allPre = allPre.next; } } System.out.println("allPre: " + (allPre != null ? allPre.val : "null")); System.out.println("start: " + (start != null ? start.val : "null")); System.out.println("end: " + (end != null ? end.val : "null")); System.out.println("allPost: " + (allPost != null ? allPost.val : "null")); // 3.执行类似于上一题的方法,反转start和end之间的链表,返回反转后的起点newStart和终点newEnd ListNode newStart = end; ListNode newEnd = start; // 只有strat和end不指向同一个结点(反转区间>1)时,才有反转的必要 if (start != end) { ListNode newPre = start; ListNode newCur = start.next; ListNode newNext = newCur.next; // 此处不用管newPre的next指向何方,因为这个newPre就是newEnd,是数组反转后的结尾,下文会令其指向allPost while(newCur != allPost) { newNext = newCur.next; newCur.next = newPre; System.out.println("结点" + newCur.val + "的反转已完成"); newPre = newCur; newCur = newNext; } } // 4.令allPre指向newStart,令allPost指向newEnd // 注意allPre的边界判断!allPre可能与newEnd(start)重合! if (allPre == newEnd) { // 如果allPre 跟 newEnd(start) 是同一个结点(m=1的情况),说明start前面没有任何元素,这时可以直接移动head到链表区间反转后的起点,令head = newStart allPre = newStart; head = allPre; } else { // 否则,是正常情况,令allPre指向newStart,从newStart到newEnd是反转区间 allPre.next = newStart; } newEnd.next = allPost; System.out.println("newEnd结点" + newEnd.val + "的下一个结点allPost是" + (allPost != null ? allPost.val : "null")); System.out.println("allPre结点" + allPre.val + "的下一个结点newStart是" + (newStart != null ? newStart.val : "null")); System.out.println("head结点" + head.val); return head; } }