当前位置:   article > 正文

LeetCode(力扣)::206.反转链表_力扣206

力扣206

目录

 1、题目

 2、思路

 3、实现

 4、结果与总结

-1、完整代码


1、题目

        我们通过阅读题干,可以得到的信息有:传给我们的是一个链表的头结点,需要我们将整个链表翻转(头变尾,尾变头),再将新链表的头结点返回。

2、思路

        题目告知我们,可以使用递归和迭代两种方法进行实现。为了便于理解,这里采用迭代的方法进行答题。我们对比一下翻转链表的两种方法:

        1、先遍历当前链表,再创建新链表,从原链表的尾结点开始,从后向前取出结点,再依次放入新链表中,全部完成之后,返回新链表的头结点。

        2、直接在原链表中进行翻转,只改变next指针的指向,让从前向后指,变成从后向前指。

 在时间复杂度上,两种方法没有优劣之分,但是由于第一种方法需要开辟新的空间来存放新链表,在空间复杂度上,第二种方法是可以节约空间的。所以我们认为第二种方法更好。

3、实现

  1. struct ListNode* prev = NULL;
  2. struct ListNode* cur = head;
  3. struct ListNode* tail;

        在函数内创建三个指针prev(前指针)、cur(当前指针)、tail(后指针)(也可以使用head指针来代替cur指针,我们这里为了方便理解,创建三个指针,以免初学者混淆概念)。

        在逻辑结构上我们想要实现的样子是:

        即prev一开始不指向任何元素,只知道他在cur指针之前,而tail永远指向cur后一个位置,在改变cur->next之后起定位作用。

        

         接下来我们就可以让三个指针依次前进,遍历整个链表,在遍历的过程当中,让cur->next从指向tail,变为指向prev。也就是从前向后指,变成从后向前指!这样我们就可以完成一次结点的翻转。

        当翻转到最后一个结点的时候,我们需要考虑一个问题。此时tail已经指向了NULL,如果再次后移,tail所指向的位置就不确定了,会变成一个野指针。而cur所指向的就会成为NULL,prev变成cur的位置,那我们应当返回的是cur还是prev呢?

        其实这两个问题都很好解释,当tail已经为NULL的时候,我们因当停止后移tail指针,以防tail指针指向不明内存空间。

  1. while(cur)//此时cur已经为NULL,tail指针不能再向后移
  2. {
  3. tail = cur->next;
  4. cur->next = prev;
  5. prev = cur;
  6. cur = tail;
  7. }

        再来考虑返回值的问题,我们需要返回的是新链表的头结点,那么我们三个指针当中,哪个是指向头结点的指针呢?首先排除tail,因为他最后一定是遍历到链表最后的位置,而cur此时的位置指向的是原链表的NULL位置。所以只有prev指向的是原链表的最后一个元素。经过一番简单的分析,我们可以得知,return的应该是prev指针。

4、结果与总结

        leetcode通过。

         此题不仅考验我们对于链表next指针的理解,同时也考察了我们对于代码的掌控能力。我们要时刻控制指针的指向位置,防止发生危险访问,并且要保证指针的顺序。严格按照前中后的顺序去移动。

-1、完整代码

  1. //写法一
  2. struct ListNode* reverseList(struct ListNode* head)
  3. {
  4. struct ListNode* prev = NULL;
  5. struct ListNode* cur = head;
  6. struct ListNode* tail;
  7. while(cur)
  8. {
  9. tail = cur->next;
  10. cur->next = prev;
  11. prev = cur;
  12. cur = tail;
  13. }
  14. return prev;
  15. }
  1. //写法二
  2. struct ListNode* reverseList(struct ListNode* head)
  3. {
  4. if(head == NULL)//如果链表为空,则不需要翻转,返回空指针
  5. {
  6. return NULL;
  7. }
  8. struct ListNode* prev = NULL;
  9. struct ListNode* cur = head;
  10. struct ListNode* tail = cur->next;
  11. while(cur)//用来控制翻转次数
  12. {
  13. //变更指向
  14. cur->next = prev;
  15. //指针移动
  16. prev = cur;
  17. cur = tail;
  18. if(tail)
  19. {
  20. tail = cur->next;
  21. }
  22. }
  23. return prev;
  24. }
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号