📅  最后修改于: 2023-12-03 15:26:09.546000             🧑  作者: Mango
在链表中,给定一个头结点和两个整数m、n,需要将链表中第m个节点到第n个节点这部分进行反转。例如,给定 1->2->3->4->5->NULL,m=2 及 n=4,返回 1->4->3->2->5->NULL。
遍历链表需用到指针操作,指针的操作主要有以下几种:
将指针指向链表头部。
判断当前指针是否为空:如果为空,则可能存在链表为空,也可以到了链表末尾。
遍历链表中的节点:得到当前节点,校验当前节点是否进行反转,如果当前节点需要反转,则将当前节点加入反转链表并遍历下一个节点,如果当前节点不需要反转,则不将当前节点加入反转链表,直接遍历下一个节点。
反转链表:在遍历完所需反转的连续几个节点之后,将反转链表进行反转。
将反转链表加入原始链表中:反转后,将反转链表的头指针与第m节点的前一个节点的指针相连接,将第n个节点的指针与反转链表的尾指针相连接即可。
public ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null) {
return null;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy;
for (int i = 1; i < m; i++) {
pre = pre.next;
}
ListNode cur = pre.next;
for (int i = m; i < n; i++) {
ListNode next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummy.next;
}
在本题中,我们需要遍历整个链表,因此需要用到两个指针:一个指向当前节点的前一个节点,另一个指向当前节点。
从头开始遍历链表:使用pre指针和cur指针,将pre指针指向目标节点的前一个节点,将cur指针指向当前节点。然后不断遍历到目标节点的结束位置。
将遍历过的节点进行反转:使用next指针记录当前节点的下一个节点,然后将当前节点的next指向之前反转节点的前一个节点,接着将之前反转节点的前一个节点的next指向当前节点。将pre指针指向当前节点,cur指针指向下一个节点。
返回整个链表的头结点即可。
该算法的时间复杂度为 O(n),其中 n 是链表的长度。在遍历链表一次后,最多可反转链表中的 n 个节点。
该算法的空间复杂度为 O(1),因为只使用了常数个额外的变量。