反转链表
题目描述:
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
样例
输入:1->2->3->4->5->NULL
输出:5->4->3->2->1->NULL
思考题:
- 请同时实现迭代版本和递归版本。
迭代版本:
思想:在原来链表的基础上,将每个结点的前驱结点改为其后继结点,进行翻转。
所以需要记录的变量有:
1.当前工作的结点。
2.当前工作的前驱结点。
3.为了防止断链,需要记录工作结点的后继结点。
/**
* 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 *next = cur->next;
//工作结点的后继指向其前驱结点,反转链表
cur->next = pre;
//前驱结点后移,工作结点后移。
pre = cur;
cur = next;
}
return 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) {
//递归版本:递归问题一般有三个步骤
//1.求解基本问题(找到递归的出口)
//当链表为空,或者链表只有一个结点,则直接返回该链表
if(!head || !head->next) return head;
//2.将大问题缩小范围转变为小问题
//递归调用reverseList函数找到最小解
ListNode *reverse = reverseList(head->next);
//3.找到小问题的解,然后将小问题的解变为大问题的解
//递归到最后一层,满足if条件,head指向5,返回上一层递归调用head=4,反转后应该是5指向4,相当于4的后继5指向4,head的后继指向head。
head->next->next = head;
//head的后继指向空
head->next = NULL;
return reverse;
}
};