当前位置:   article > 正文

LeetCode 206.反转链表(C++)_letcode206

letcode206

题目地址:力扣

解法1:三指针法

反转链表,那么从链表头结点开始,头结点的next要指向空,那么就需要一个后继节点来保存头结点的后一个节点。有后继节点那么也需要一个当前节点(用head也可以,但是为了清楚表明可以另外用一个当前节点)。考虑头结点的后一节点要指向头结点,因此还需要一个前置节点来保存之前的节点。

这种方法总共需要借助三个指针来实现,分别是记录当前节点,上一节点以及后一节点。

思路:只要后一节点不为空,那么

1、将后继节点指向当前节点的next,即保存当前节点的下一节点

2、将当前节点的next指向前置节点,即反转过程

3、将前置节点指向当前节点(当前节点变成了下一次操作的前置节点)

4、将当前节点指向后继节点,即两个节点指向相同

  1. class Solution {
  2. public:
  3. ListNode* reverseList(ListNode* head) {
  4. ListNode *prevNode = nullptr;
  5. ListNode *currNode = head;
  6. ListNode *nextNode = head;
  7. while(nextNode != nullptr)
  8. {
  9. nextNode = currNode->next;
  10. currNode->next = prevNode;
  11. prevNode = currNode;
  12. currNode = nextNode;
  13. }
  14. return prevNode;
  15. }
  16. };

解法2:头插法

思路也很简单,正向链表只需要用头插法就可以反转了,但是这就需要一个哨兵节点来用于头插,最后返回的也是哨兵节点的next

  1. class Solution {
  2. public:
  3. ListNode* reverseList(ListNode* head) {
  4. // 哨兵节点
  5. ListNode sentry(0);
  6. ListNode *nextNode = head;
  7. // 下一节点非空就执行头插操作
  8. while (nextNode != nullptr)
  9. {
  10. nextNode = head->next;
  11. head->next = sentry.next;
  12. sentry.next = head;
  13. head = nextNode;
  14. }
  15. return sentry.next;
  16. }
  17. };

解法3:递归法

涉及到需要反转的,就可以想可以从后往前做,但是单链表不能找其头结点,所以只能是用递归的方式从后往前

  1. class Solution {
  2. public:
  3. ListNode* reverseList(ListNode* head) {
  4. // 只要当前节点为空或者当前节点的next为空,都返回当前节点
  5. if (head == nullptr || head->next == nullptr)
  6. return head;
  7. // 都不为空,那么就递归将原链表的尾节点带出来,赋给newHead
  8. ListNode *newHead = reverseList(head->next);
  9. // 当前节点的后继节点的next指针指向当前节点
  10. head->next->next = head;
  11. // 反转后原链表头结点的next应该为空,因此每次都把head的next置为空
  12. head->next = nullptr;
  13. return newHead;
  14. }
  15. };

解法4:尾置递归法

思路:尾置递归和前面的递归有所不同,递归的返回不再是从递归的里面出来,而是进入下一层递归。这也就意味着链表是从前往后走的,那么改变next之前就需要存下next指向的地方,因此需要用一个新的节点来保存。同时这个递归函数应该接受两个参数,所以不能直接写在reverseList的里面。

  1. class Solution {
  2. public:
  3. ListNode* reverse(ListNode* prev, ListNode *curr) {
  4. ListNode *nextNode;
  5. // 当前节点为空,说明到了prev正好指向链尾节点(新链头)
  6. if (curr == nullptr)
  7. return prev;
  8. // 当前节点不空,就先存下当前节点的next,然后把当前节点的next指向prev
  9. nextNode = curr->next;
  10. curr->next = prev;
  11. // 递归执行下一个节点
  12. return reverse(curr, nextNode);
  13. }
  14. ListNode* reverseList(ListNode* head) {
  15. return reverse(nullptr, head);
  16. }
  17. };

Accepted

  • 28/28 cases passed (8 ms)
  • Your runtime beats 48.56 % of cpp submissions
  • Your memory usage beats 21.96 % of cpp submissions (8.2 MB)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/209831
推荐阅读
相关标签
  

闽ICP备14008679号