原题目链接
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
直接实现
定义一个无意义的新头结点,引入两个指针:一个用于延链表遍历;另一个用于暂存位置,目的是为了向前插入。 迭代此过程至链表结束。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head)
return nullptr;
ListNode *nh = new ListNode(-1); // 定义新-空 头结点
nh -> next = NULL;
ListNode *t = head; // 遍历指针
ListNode *tmp; // 暂存指针
while(t != NULL)
{
tmp = t;
t = t -> next;
tmp -> next = nh ->next; // 向后连接
nh -> next = tmp; // 向前插入
}
return nh -> next;
}
};
复杂度分析:
- 时间复杂度:O(N)
- 空间复杂度:O(1)
其他方式
还有一种方式使用递归方式。
思路比价巧妙:
但是复杂度更高:空间复杂度O(N)
官方题解写法:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head -> next == NULL)
return head;
ListNode *p = reverseList(head -> next);
head -> next -> next = head;
head -> next = NULL;
return p;
}
};
写的复杂
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head)
return nullptr;
return reverse(head, head, head->next);
}
ListNode* reverse(ListNode* head, ListNode* first, ListNode* target){
if(!target)
return head;
first -> next = target -> next;
ListNode* tmp = target -> next;
target -> next = head;
return reverse(target, first, tmp);
}
};
复杂度分析:
- 时间复杂度:O(N)
- 空间复杂度:O(N)
写在最后
晚安