返回

走出编程困境,逆转链表逆转人生

后端







## 算法解析

链表反转看似复杂,但其本质很简单:就是将链表中的一段区间[left, right]内的元素顺序颠倒。为了实现这一目标,我们可以采用递归或迭代两种方法。

### 递归法

递归法是解决链表反转问题的一种经典方法。其思路如下:

1. 如果链表为空或仅包含一个元素,则直接返回。
2. 否则,将链表的头结点记为head,将剩余的链表记为tail。
3. 反转tail,并将head连接到tail的末尾。
4. 将head返回作为反转后的链表。

递归法的代码实现如下:

```cpp
ListNode* reverseBetween(ListNode* head, int left, int right) {
  if (left == right) {
    return head;
  }

  ListNode* dummy = new ListNode(0);
  dummy->next = head;

  ListNode* pre = dummy;
  for (int i = 1; i < left; i++) {
    pre = pre->next;
  }

  ListNode* cur = pre->next;
  ListNode* next;
  for (int i = 0; i < right - left; i++) {
    next = cur->next;
    cur->next = pre->next;
    pre->next = cur;
    cur = next;
  }

  return dummy->next;
}

迭代法

迭代法也是解决链表反转问题的一种常见方法。其思路如下:

  1. 将链表的头结点记为head,将要反转的区间记为[left, right]。
  2. 创建一个新的链表node,并将head连接到node的末尾。
  3. 遍历链表,将每个元素从head中移除,并将其插入到node的末尾。
  4. 将node连接到head的末尾,并返回head。

迭代法的代码实现如下:

ListNode* reverseBetween(ListNode* head, int left, int right) {
  if (left == right) {
    return head;
  }

  ListNode* dummy = new ListNode(0);
  dummy->next = head;

  ListNode* pre = dummy;
  for (int i = 1; i < left; i++) {
    pre = pre->next;
  }

  ListNode* cur = pre->next;
  ListNode* next;
  for (int i = 0; i < right - left; i++) {
    next = cur->next;
    cur->next = pre->next;
    pre->next = cur;
    cur = next;
  }

  pre->next->next = next;
  return dummy->next;
}

总结

链表反转是一种常见的算法题,也是解决实际问题的一大利器。掌握链表反转的技巧,可以帮助你轻松应对各种编程挑战,成为一名优秀的程序员。