当前位置:   article > 正文

LeetCode刷题——206. 反转链表(简单)——迭代(双指针)_leetcode206

leetcode206

我的解法:双指针迭代

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * ListNode *next;
  6. * ListNode() : val(0), next(nullptr) {}
  7. * ListNode(int x) : val(x), next(nullptr) {}
  8. * ListNode(int x, ListNode *next) : val(x), next(next) {}
  9. * };
  10. */
  11. class Solution {
  12. public:
  13. ListNode* reverseList(ListNode* head) {
  14. ListNode* curr=head;
  15. ListNode* pre=nullptr;
  16. while(curr!=nullptr){
  17. ListNode* nextTemp=curr->next;
  18. curr->next=pre;
  19. pre=curr;
  20. curr=nextTemp;
  21. }
  22. return pre;
  23. }
  24. };

官方解法

1.迭代

方法一:迭代
假设链表为 1 →2 →3 → ∅,我们想要把它改成 ∅←1←2←3。

遍历链表时,将当前节点的next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。

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

复杂度分析

  • 时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。

  • 空间复杂度:O(1)。

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2.递归

递归版本稍微复杂一些,其关键在于反向工作。假设链表的其余部分已经被反转,现在应该如何反转它前面的部分?

假设链表为:n1→…→nk−1→nk→nk+1→…→nm→∅

若从节点 nk+1到 nm已经被反转,而我们正处于nk。

n1→…→nk−1→nk→nk+1←…←nm
​我们希望 nk+1的下一个节点指向 nk。

所以,nk.next.next=nk。

需要注意的是 n1的下一个节点必须指向∅。如果忽略了这一点,链表中可能会产生环。

  1. class Solution {
  2. public:
  3. ListNode* reverseList(ListNode* head) {
  4. if (!head || !head->next) {
  5. return head;
  6. }
  7. ListNode* newHead = reverseList(head->next);
  8. head->next->next = head;
  9. head->next = nullptr;
  10. return newHead;
  11. }
  12. };

复杂度分析

  • 时间复杂度:O(n),其中 n 是链表的长度。需要对链表的每个节点进行反转操作。
  • 空间复杂度:O(n),其中 n 是链表的长度。空间复杂度主要取决于递归调用的栈空间,最多为 n 层。

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-by-leetcode-solution-d1k2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论区关于递归方式的解析:

NoColor96https://leetcode-cn.com/u/nocolor96/

:这里递归的确不好理解,我研究了会儿,尝试解释一下

  1. /**
  2. * 以链表1->2->3->4->5举例
  3. * @param head
  4. * @return
  5. */
  6. public ListNode reverseList(ListNode head) {
  7. if (head == null || head.next == null) {
  8. /*
  9. 直到当前节点的下一个节点为空时返回当前节点
  10. 由于5没有下一个节点了,所以此处返回节点5
  11. */
  12. return head;
  13. }
  14. //递归传入下一个节点,目的是为了到达最后一个节点
  15. ListNode newHead = reverseList(head.next);
  16. /*
  17. 第一轮出栈,head为5,head.next为空,返回5
  18. 第二轮出栈,head为4,head.next为5,执行head.next.next=head也就是5.next=4,
  19. 把当前节点的子节点的子节点指向当前节点
  20. 此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开4.next=null
  21. 此时链表为1->2->3->4<-5
  22. 返回节点5
  23. 第三轮出栈,head为3,head.next为4,执行head.next.next=head也就是4.next=3,
  24. 此时链表为1->2->3<->4<-5,由于3与4互相指向,所以此处要断开3.next=null
  25. 此时链表为1->2->3<-4<-5
  26. 返回节点5
  27. 第四轮出栈,head为2,head.next为3,执行head.next.next=head也就是3.next=2,
  28. 此时链表为1->2<->3<-4<-5,由于2与3互相指向,所以此处要断开2.next=null
  29. 此时链表为1->2<-3<-4<-5
  30. 返回节点5
  31. 第五轮出栈,head为1,head.next为2,执行head.next.next=head也就是2.next=1,
  32. 此时链表为1<->2<-3<-4<-5,由于1与2互相指向,所以此处要断开1.next=null
  33. 此时链表为1<-2<-3<-4<-5
  34. 返回节点5
  35. 出栈完成,最终头节点5->4->3->2->1
  36. */
  37. head.next.next = head;
  38. head.next = null;
  39. return newHead;

另外一些无用的暴力解法:

触不可及

:啊这~ 按照题目测试只要值颠倒就行啊,击败100%、95.95%

  1. class Solution {
  2. public ListNode reverseList(ListNode head) {
  3. ListNode ans = null;
  4. for (ListNode x = head; x != null; x = x.next) {
  5. ans = new ListNode(x.val,ans);
  6. }
  7. return ans;
  8. }
  9. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/209829
推荐阅读
相关标签
  

闽ICP备14008679号