当前位置:   article > 正文

力扣刷题笔记——反转链表_力扣 反转链表

力扣 反转链表

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

经典问题反转链表

这里给出四种解法

1.双指针

这种方法是用一个next指针记录当前节点的下一个节点,一个pre指针记录当前节点的前一个节点。

只需要遍历一遍链表就可以完成链表的反转

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

2.栈

这种方法使用了额外的堆栈空间,但能够有效地反转链表。

  1. class Solution {
  2. public:
  3. ListNode* reverseList(ListNode* head) {
  4. // 如果链表为空或只有一个节点,直接返回原链表
  5. if (!head || !head->next)
  6. return head;
  7. stack<ListNode*> stk; // 创建一个堆栈,用于存储链表节点
  8. ListNode* curr = head; // 创建指针curr,用于遍历原始链表
  9. // 将链表节点逐个压入堆栈
  10. while (curr) {
  11. stk.push(curr);
  12. curr = curr->next;
  13. }
  14. ListNode* newhead = stk.top(); // 堆栈的顶部节点作为新链表的头部
  15. curr = newhead;
  16. // 从堆栈中弹出节点,并重新连接链表节点
  17. while (!stk.empty()) {
  18. curr->next = stk.top();
  19. curr = curr->next;
  20. stk.pop();
  21. }
  22. curr->next = nullptr; // 将新链表的尾部节点的next设为nullptr,结束链表
  23. return newhead; // 返回新链表的头部
  24. }
  25. };

3.递归

利用函数的栈来辅助完成反转

基本思想是将原始链表的头部节点不断地移到新链表的尾部,从而实现链表的反转。这个方法不需要额外的堆栈空间,但需要小心处理链表节点的指针。函数将递归地反转链表,直到链表的末尾,然后返回新链表的头部。

首先将问题拆为两部分

1.反转头节点

2.反转头节点之外的所有节点

  1. class Solution {
  2. public:
  3. ListNode* reverseList(ListNode* head) {
  4. // 如果链表为空或只有一个节点,直接返回原链表
  5. if (!head || !head->next)
  6. return head;
  7. //反转头节点外的所有节点
  8. // 调用递归函数,将head->next作为新链表的头部
  9. ListNode* newhead = reverseList(head->next);
  10. //反转头节点
  11. // 将head节点的下一个节点的下一个指针指向head,实现反转
  12. head->next->next = head;
  13. // 将head节点的下一个指针设为nullptr,结束新链表的尾部
  14. head->next = nullptr;
  15. return newhead; // 返回新链表的头部
  16. }
  17. };

4.哈希表

可以用一个哈希表来储存每个节点的前一个节点

  1. class Solution {
  2. public:
  3. ListNode* reverseList(ListNode* head) {
  4. // 如果链表为空或只有一个节点,直接返回原链表
  5. if (!head || !head->next)
  6. return head;
  7. unordered_map<ListNode*, ListNode*> hash; // 创建哈希表,存储每个节点和它们的前一个节点
  8. ListNode* curr = head; // 当前节点
  9. // 构建哈希表
  10. while (curr->next) {
  11. hash.insert({curr->next, curr}); // 存储当前节点的下一个节点和当前节点的映射关系
  12. curr = curr->next; // 移动到下一个节点
  13. }
  14. ListNode* newhead = curr; // 新链表的头部为原始链表的末尾
  15. curr = newhead; // 重新将curr指向新链表的头部
  16. // 根据哈希表中的映射关系重新连接节点的指针
  17. while (curr) {
  18. curr->next = hash[curr]; // 重新连接节点的next指针
  19. curr = curr->next; // 移动到下一个节点
  20. }
  21. head->next = nullptr; // 将原始链表的头部的next设为nullptr,结束链表
  22. return newhead; // 返回新链表的头部
  23. }
  24. };

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

闽ICP备14008679号