LeetCode每日一题 206.反转链表

206.反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

昨天困难级的K个一组反转链表,着实费脑子,需要考虑很多的细节,一不留神就是错。由难入易,夯实基础,今天看一看简单的反转链表。
反转链表相当于K个一组反转的子模块,即只反转一组。

迭代法:根据示例,当我们遍历链表时,需要为了后续遍历,记录当前结点的后续,同时,将当前结点的next指向前续。因此,每一次迭代需要保留当前结点和前续。第一个结点在反转后后续为NULL,因此前续初始值为NULL。

/**
 * 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 head;
        /*迭代*/
        ListNode* p=head;
        ListNode* pre=NULL,*temp=NULL;
        while(p){
            temp=p->next;
            p->next=pre;
            pre=p;
            p=temp;
        }
        return pre;
    }
};

递归法:每一次看到别人写的递归,就和LeetCode上许多朋友说的,我觉得我就是个傻子。。。hhhh,不过相信各位朋友都会成为大佬的!菜鸡如我,也要好好学习递归呀。
这道题的递归和三角形、斐波那契等具体问题不同,很难抽象出一个递归方程。递归法是先向后遍历到链表的最后一个元素,再出栈反向来反转链表。
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) {
        if(head==NULL || head->next==NULL)
            return head;
        /*递归*/
        ListNode* p=reverseList(head->next);
        head->next->next=head;
        head->next=NULL;
        return p;
    }
};

以链表[1,2,3,4,5]为例,递归最深时为reverseList(5),此时返回的p为结点5,返回到第4层递归,head指向结点4,将5的next指向4,4的next指向NULL,此时新链表为5->4->NULL,返回p(此次可以看出,递归返回的是新链表的头)。按序扩充即可。

你可能感兴趣的:(LeetCode每日一题 206.反转链表)