题目及基本数据结构
反转一个单链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
题目分析
本题目要求对给出的单链表进行反转。
不难看出有递归和迭代两种方式。
迭代法
该题有如下问题,如果我们采用迭代的方式来对链表进行反转,那么就相当于我们需要记录反向的指针。那么也就是说我们需要一个额外的指针来对每次反转后的原指针进行记录,避免后一个元素在指针反转后索引不到。除此之外,反转后的链表的尾节点(原头节点)必须指向null。因此,我们需要两个节点做额外空间。
此处我们采用双指针法。在C++中,创建指针相对好操作,所以我们采用操作指针的方式。
创建Listnode或Listnode * 均可,区别在于我们使用.还是->来进行操作。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre;
ListNode* curr;
pre = NULL;
curr = head;
ListNode* temp;
while(curr != NULL){
temp = curr->next;
curr->next = pre;
pre = curr;
curr = temp;
}
return pre;
}
};
这里还是要注意最后返回的是pre还是curr。
##递归法
递归的思想,我理解此处的递归就是:
找到最后一个要解决的问题,并找到其通解,在调用的时候,确定递归停止条件,并进行从大到小的调用。实际问题的解决是从最深层递归到最浅层递归的输出过程。代码如下:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head || !head->next){
return head;
}
ListNode * head_end = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return head_end;
}
};
头插法
这种方法需要创建一个新链表,比较简单,此处不在多加叙述。