【剑指offer】3.反转链表

 

总目录:

 

算法之旅导航目录

 

 

1.问题描述
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
数据范围: 0<=≤n≤1000
要求:空间复杂度 O(1),时间复杂度 O(n) 。

如当输入链表{1,2,3}时,

经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:

 

2.题目解析:

注意题干,

1要求空间复杂度为O(1),即过程中不允许使用导致内存增加的操作;

2.要求时间复杂度为O(n),

想到的方法有

1简单地迭代,逐个由从前向后指变为从后向前指,需要注意边界条件;

2.递归,最后一个非空节点即为返回值,往回迭代的过程中改变指向,注意最开始的head最终要指向null;

3.不能用栈,会造成空间复杂度上升,从而不符合=O(1)的要求;

 

3.cpp代码

简单迭代法

 1 /*
 2 struct ListNode {
 3     int val;
 4     struct ListNode *next;
 5     ListNode(int x) :
 6             val(x), next(NULL) {
 7     }
 8 };*/
 9 class Solution {
10   public:
11     ListNode* ReverseList(ListNode* pHead) {
12         if (pHead == NULL) {
13             return pHead;
14         }
15 
16         ListNode* pPre = NULL;
17         ListNode* pNext = NULL;
18         while (pHead != NULL) {
19 
20             //获取next
21             pNext = pHead->next;
22 
23             //翻转指向
24             pHead->next = pPre;
25 
26             //更新指针
27             if (pNext == NULL) {
28                 return pHead;
29             }
30             pPre = pHead;
31             pHead = pNext;
32         }
33 
34         return pHead;
35     }
36 };
View Code

递归法

 1 /*
 2 struct ListNode {
 3     int val;
 4     struct ListNode *next;
 5     ListNode(int x) :
 6             val(x), next(NULL) {
 7     }
 8 };*/
 9 class Solution {
10   public:
11     void recurve(ListNode* cur, ListNode* next, ListNode*& newHead) {
12         //终止条件
13         if (next == NULL) {
14             newHead = cur;//cherry pick
15             return;
16         }
17 
18         //递归调用
19         recurve(next, next->next, newHead);
20 
21         //本级任务
22         //下一个非空节点指向当前节点
23         cur->next->next = cur;
24         cur->next=NULL;
25     }
26 
27 
28     ListNode* ReverseList(ListNode* pHead) {
29         //防止输入为空
30         if (pHead == NULL) {
31             return pHead;
32         }
33 
34         //去接收最终的head
35         ListNode* newHead = NULL;
36         recurve(pHead, pHead->next, newHead);
37 
38         return newHead;
39     }
40 };
View Code

 虽然但是,用栈的方法,参考一下

 1 /*
 2 struct ListNode {
 3     int val;
 4     struct ListNode *next;
 5     ListNode(int x) :
 6             val(x), next(NULL) {
 7     }
 8 };*/
 9 class Solution {
10   public:
11     ListNode* ReverseList(ListNode* pHead) {
12         //存入栈中
13         stack<ListNode*> sp;
14         while (pHead != NULL) {
15             sp.push(pHead);
16             pHead = pHead->next;
17         }
18 
19         if (sp.empty()) {
20             return NULL;
21         }
22 
23         //取head
24         ListNode* cur=sp.top();
25         pHead=cur;//维护返回值
26         sp.pop();
27 
28         //依次翻转指向
29         while (!sp.empty()) {
30             ListNode* temp = sp.top();
31             sp.pop();
32             cur->next=temp;
33             cur=temp;
34         }
35 
36         //最后一个非空节点,不要让其维持原指向
37         cur->next=NULL;
38 
39         return pHead;
40     }
41 };
View Code

 

 

 

posted @ 2022-11-09 13:01  啊原来是这样呀  阅读(32)  评论(0编辑  收藏  举报