【力扣100题】09.反转链表
一、题目描述给定单链表的头节点head反转链表并返回反转后的链表。示例输入head [1,2,3,4,5] 输出[5,4,3,2,1] 输入head [1,2] 输出[2,1] 输入head [] 输出[]二、核心思路关键观察反转链表就是改变每个节点的 next 指针指向让它指向前一个节点而不是后一个节点。原链表: 1 - 2 - 3 - 4 - 5 - nullptr ↑ ↑ pre head 反转后: 1 - 2 - 3 - 4 - 5 - nullptr ↑ ↑ pre head三、代码实现方法一迭代法双指针✅/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */classSolution{public:ListNode*reverseList(ListNode*head){ListNode*prenullptr;while(head!nullptr){ListNode*curhead-next;// 保存下一个节点head-nextpre;// 反转指针prehead;// pre 前进headcur;// head 前进}returnpre;// pre 是新的头节点}};代码图解初始状态 nullptr - 1 2 - 3 - 4 - 5 - nullptr pre head 第1步cur2, head-nextnullptr, pre1, head2 nullptr - 1 2 - 3 - 4 - 5 - nullptr pre head 第2步cur3, head-next1, pre2, head3 nullptr - 1 - 2 3 - 4 - 5 - nullptr pre head 第3步cur4, head-next2, pre3, head4 nullptr - 1 - 2 - 3 4 - 5 - nullptr pre head 第4步cur5, head-next3, pre4, head5 nullptr - 1 - 2 - 3 - 4 5 - nullptr pre head 第5步curnullptr, head-next4, pre5, headnullptr nullptr - 1 - 2 - 3 - 4 - 5 pre(新头) 返回 pre!复杂度分析复杂度值时间O(n)空间O(1)四、递归解法递归法原理递归的思路假设后面的链表已经反转好了我们只需要把当前节点接上去。classSolution{public:ListNode*reverseList(ListNode*head){// 递归终止条件空链表或只有一个节点if(headnullptr||head-nextnullptr){returnhead;}// 递归反转后面的链表ListNode*newHeadreverseList(head-next);// 让下一个节点的 next 指向当前节点head-next-nexthead;// 当前节点的 next 置为 nullptrhead-nextnullptr;returnnewHead;}};递归图解reverseList(1-2-3-4-5) 递归调用链深入: reverse(1) - reverse(2) - reverse(3) - reverse(4) - reverse(5) reverse(5) 返回 5 (终止条件: head-next nullptr) 回溯过程: reverse(4): 5-next 4, 4-next nullptr, 返回 5 reverse(3): 4-next 3, 3-next nullptr, 返回 5 reverse(2): 3-next 2, 2-next nullptr, 返回 5 reverse(1): 2-next 1, 1-next nullptr, 返回 5 最终: 5 - 4 - 3 - 2 - 1 - nullptr复杂度分析复杂度值时间O(n)空间O(n) 递归栈五、方法对比方法时间空间推荐度迭代法O(n)O(1) ⭐⭐⭐⭐最优递归法O(n)O(n)⭐⭐ 简洁但占用栈空间六、完整测试代码#includeiostreamusingnamespacestd;// 链表节点定义structListNode{intval;ListNode*next;ListNode():val(0),next(nullptr){}ListNode(intx):val(x),next(nullptr){}ListNode(intx,ListNode*next):val(x),next(next){}};classSolution{public:// 迭代法反转链表ListNode*reverseList(ListNode*head){ListNode*prenullptr;while(head!nullptr){ListNode*curhead-next;head-nextpre;prehead;headcur;}returnpre;}// 递归法反转链表ListNode*reverseList_recursive(ListNode*head){if(headnullptr||head-nextnullptr){returnhead;}ListNode*newHeadreverseList_recursive(head-next);head-next-nexthead;head-nextnullptr;returnnewHead;}};// 测试辅助函数voidprintList(ListNode*head){cout[;while(head!nullptr){couthead-val;if(head-next)cout,;headhead-next;}cout]endl;}intmain(){Solution sol;// 创建链表: 1 - 2 - 3 - 4 - 5ListNode*headnewListNode(1);head-nextnewListNode(2);head-next-nextnewListNode(3);head-next-next-nextnewListNode(4);head-next-next-next-nextnewListNode(5);cout原链表: ;printList(head);ListNode*reversedsol.reverseList(head);cout反转后: ;printList(reversed);return0;}输出原链表: [1,2,3,4,5] 反转后: [5,4,3,2,1]七、总结方法关键点迭代法pre、head 双指针三步走保存→反转→前进递归法先递归反转后面再处理当前节点核心都是让每个节点的 next 指针指向它的前一个节点。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2471364.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!