题目描述
解法 双指针法
定义一个 pre指针指向上一个结点和cur指针指向当前节点,利用临时指针tmp=cur->next不断更新cur
错误案例
/**
* 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) {
if(head == NULL)
return nullptr;
ListNode *pre = head;
ListNode *cur = pre -> next;
ListNode *tmp = cur -> next;
while(tmp) {
cur -> next = pre;
pre = cur;
cur = tmp;
tmp = cur -> next;
}
head -> next = NULL;
cur -> next = pre;
return cur;
}
};
觉得题目简单草草应付的代码
没有考虑到tmp可能是空指针,导致空指针报错,同时导致反转结束时得单独处理。
改进:
将pre的初始值定义为空指针,cur定义为head,当cur为空时说明pre到达头节点,改进代码为
/**
* 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) {
ListNode *pre = NULL;
ListNode *cur = head;
while(cur) {
ListNode *tmp = cur -> next;
cur -> next = pre;
pre = cur;
cur = tmp;
}
head = pre;
return head;
}
};
时间复杂度O(n),空间复杂度O(1)
解法二 递归法
/**
* 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) {
if(head == NULL || head -> next == NULL ) {
return head;
}
ListNode *tmp = reverseList(head -> next);
head -> next -> next = head;
head -> next = NULL;
return tmp;
}
};
head -> next -> next = head 可以让当前节点的下一个节点的next指针指向自己
利用递归的栈的特性省去一个pre指针。
妙在往回递归之后,tmp一直都是最后一次的head。
时间复杂度O(n) ,空间复杂度O(n)