剑指offer:反转链表

原题链接https://www.acwing.com/problem/content/description/33/

参考链接:https://www.acwing.com/solution/content/6583/ (有动画)
y总:https://www.acwing.com/solution/content/743/

迭代

在这里插入图片描述

一个pre指针,保留前继节点,一个cur,指向当前节点,一个next,指向下一个节点。

每次:
next保存cur的下一个节点
cur的next指向pre
向后移动一位:pre移到cur,cur移动next

/**
 * 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 = nullptr;
        auto cur = head;
        while(cur)
        {
        	// 存一下下一个节点
            ListNode* next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
		
		// while结束的时候,cur为NULL,pre正好是头节点
        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) {
        if(head == NULL) return NULL;
        if(head->next == NULL) return head;
        
        ListNode* p = head;
		
		// 先找到最后一个节点
        while(p->next->next != NULL)
        {
            p = p->next;
        }
        
        // 新建一个
        ListNode* new_head = p->next;
        p->next = NULL;
        ListNode* p2 = new_head;
        
        while(1)
        {
            p = head;
            
            if(p->next == NULL)
            {
                p2->next = p;
                break;
            }
            
            while(p->next->next)
            {
                p = p->next;
            }
            
            p2->next = p->next;
            p->next = NULL;
            p2 = p2->next;
        }
        
        return new_head;
    }
};

递归:

在这里插入图片描述

/**
 * 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) {
        /*
            递归版本:
            首先我们先考虑 reverseList 函数能做什么,
            它可以翻转一个链表,并返回新链表的头节点,
            也就是原链表的尾节点。
            所以我们可以先递归处理 reverseList(head->next),这样我
            们可以将以head->next为头节点的链表翻转,并得到原链表的
            尾节点tail,此时head->next是新链表的尾节点,我们令它的
            next指针指向head,并将head->next指向空即可将整个链表翻转
            ,且新链表的头节点是tail。
        */
        if(!head || !head->next) return head;
        
        // 处理head->next
        ListNode* tail = reverseList(head->next);
        
        // 把head添加到最后,同时把head->next置为空
        // 上面的递归函数执行完以后,head->next是新链表的尾节点
        // 我们让新链表的尾节点的next为原来的列表的头节点,完成反转
        head->next->next = head;
        // head->next置空
        head->next = nullptr;
        return tail;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值