如何实现链表反转
今天是第四天,坚持是一件很酷的事,所以加油!
题目:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
给出的代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
}
}
方法1
思路
看到方向,第一想法就是利用栈来实现,仔细想想确实也可以实现,也挺简单的。
代码实现
class Solution {
public:
ListNode* reverseList(ListNode* head) {
stack<int> res; //栈先进后出实现反向;
while(head!=NULL){
res.push(head->val);
head=head->next;
}
ListNode* mid=new ListNode(0);
ListNode* ans=mid; //新建一个节点,并使mid和ans指向它
while(!res.empty()){
ListNode* tmp=new ListNode(res.top()); //新建节点保存栈弹出结果
mid->next=tmp;
mid=mid->next; //连接成链表
res.pop();
}
return ans->next;
}
};
时间复杂度
首先遍历链表,然后再遍历栈,我们可以轻易看出时间复杂度是O(n).
空间复杂度
额外开辟了一个栈,以及一个链表来实现,所以空间复杂度使O(n)。
方法2
直接利用链表的相关操作实现反向,即使节点的下一个指针指向前一个
实现
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* curr=head;
ListNode* pre=nullptr; //指向一个空指针
ListNode* tmp;
while(curr){
tmp=curr->next; //中间变量保存下一个值
curr->next=pre; //指向前一个
pre=curr; //后移
curr=tmp;
}
return pre;
}
};
时间复杂度
遍历链表,在遍历的过程中修改链表的指针。所以时间复杂度是O(n).
空间复杂度
实现过程中,额外开辟了几个指针,所以空间复杂度为O(1)。