力扣刷题:5-反转链表 II(92)

138 阅读1分钟

这是一道局部翻转链表的题,可以这样实现:

假如要翻转链表的第M到第N个节点:

  1. 首先跳过待翻转链表的头M个节点
  2. 然后把第M+1个节点当做头节点,翻转N-M+1个节点
  3. 修改第M个节点的下一个节点为翻转后新的头节点
  4. 完成翻转

这里还使用了一个虚拟头节点的技巧,因为如果是从第一个节点开始翻转,那么当前头节点会被翻转到链表中间,而新的头节点变成了其他节点,增加虚拟头节点来辅助翻转逻辑,可以比较方便的保存头节点的引用。

下面是使用C语言实现的功能:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

// 翻转N个节点
struct ListNode* reverseN(struct ListNode* head, int n) {
    if (n == 1) {
        return head;
    }
    
    struct ListNode* next = head->next;
    struct ListNode* curr = reverseN(next, n - 1);
    head->next = next->next;
    next->next = head;
    return curr;
}

struct ListNode* reverseBetween(struct ListNode* head, int left, int right){
    struct ListNode prevObject = {
        .val = 0,
        .next = head
    };
    struct ListNode* prev = &prevObject;
    head = prev;
    for (int i = 1; i < left; i++) {
        head = head->next;
    }
    head->next = reverseN(head->next, right - left + 1);
    return prev->next;
}