题目:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
头插法
Java实现
public static ListNode reverseBetween2(ListNode head, int left, int right) {// 设置 dummyNode 是这一类问题的一般做法ListNode dummyNode = new ListNode(-1);dummyNode.next = head;ListNode pre = dummyNode;for (int i = 0; i < left - 1; i++) {pre = pre.next;}ListNode cur = pre.next;ListNode next;for (int i = 0; i < right - left; i++) {next = cur.next;cur.next = next.next;next.next = pre.next; //注意此处,为啥不能用curpre.next = next;}return dummyNode.next;}
python实现
def reverseBetween2(self, head, left, right):# 设置 dummyNode 是这一类问题的一般做法dummy_node = ListNode(-1)dummy_node.next = headpre = dummy_nodefor _ in range(left - 1):pre = pre.nextcur = pre.nextfor _ in range(right - left):next = cur.nextcur.next = next.nextnext.next = pre.nextpre.next = nextreturn dummy_node.next
穿针引线法
Java实现
public static ListNode reverseListNode(ListNode head, int left, int right) {//特殊情况考虑if(head == null || head.next == null || left == right){return head;}//建立虚拟节点ListNode dummyNode = new ListNode(-1);dummyNode.next = head;ListNode temp = dummyNode;int count =0;//找到left前一个节点for(;count < left-1;count++){temp = temp.next;}//反转链表开始的位置ListNode leftNode = temp.next;//记录反转后链表的头节点ListNode rightNode = null;ListNode next = null;//开始反转链表for(;count<right;count++){next = leftNode.next;leftNode.next = rightNode;rightNode = leftNode;leftNode = next;}ListNode curRight = rightNode;//遍历到链表的尾部while (curRight.next != null){curRight = curRight.next;}//让反转区间和区间后面的位置相连接curRight.next = leftNode;//让区间前面的和反转区间相连接temp.next = rightNode;return dummyNode.next;}
python实现
def reverseBetween(self, head, left, right):def reverse_linked_list(head):# 也可以使用递归反转一个链表pre = Nonecur = headwhile cur:next = cur.nextcur.next = prepre = curcur = next# 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论dummy_node = ListNode(-1)dummy_node.next = headpre = dummy_node# 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点# 建议写在 for 循环里,语义清晰for _ in range(left - 1):pre = pre.next# 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点right_node = prefor _ in range(right - left + 1):right_node = right_node.next# 第 3 步:切断出一个子链表(截取链表)left_node = pre.nextcurr = right_node.next# 注意:切断链接pre.next = Noneright_node.next = None# 第 4 步:反转链表的子区间reverse_linked_list(left_node)# 第 5 步:接回到原来的链表中pre.next = right_nodeleft_node.next = currreturn dummy_node.next