《剑指offer》第二十四题:反转链表

Posted zsy-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指offer》第二十四题:反转链表相关的知识,希望对你有一定的参考价值。

// 面试题24:反转链表
// 题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的
// 头结点。

#include <cstdio>
#include "List.h"

ListNode* ReverseList(ListNode* pHead)
{
    ListNode* pRevHead = nullptr;
    ListNode* pNode = pHead; //当前节点
    ListNode* pPrev = nullptr; //前一个节点

    while (pNode != nullptr)
    {
        ListNode* pNext = pNode->m_pNext;

        //如果到了尾节点
        if (pNext == nullptr)
            pRevHead = pNode;

        pNode->m_pNext = pPrev; //当前节点连接到上一个节点

        pPrev = pNode;
        pNode = pNext;
    }
    return pRevHead;
}
技术图片
// ====================测试代码====================
ListNode* Test(ListNode* pHead)
{
    printf("The original list is: 
");
    PrintList(pHead);

    ListNode* pReversedHead = ReverseList(pHead);

    printf("The reversed list is: 
");
    PrintList(pReversedHead);

    return pReversedHead;
}

// 输入的链表有多个结点
void Test1()
{
    ListNode* pNode1 = CreateListNode(1);
    ListNode* pNode2 = CreateListNode(2);
    ListNode* pNode3 = CreateListNode(3);
    ListNode* pNode4 = CreateListNode(4);
    ListNode* pNode5 = CreateListNode(5);

    ConnectListNodes(pNode1, pNode2);
    ConnectListNodes(pNode2, pNode3);
    ConnectListNodes(pNode3, pNode4);
    ConnectListNodes(pNode4, pNode5);

    ListNode* pReversedHead = Test(pNode1);

    DestroyList(pReversedHead);
}

// 输入的链表只有一个结点
void Test2()
{
    ListNode* pNode1 = CreateListNode(1);

    ListNode* pReversedHead = Test(pNode1);

    DestroyList(pReversedHead);
}

// 输入空链表
void Test3()
{
    Test(nullptr);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();

    return 0;
}
测试代码

分析:多考虑边界值。

技术图片
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        
        ListNode* pRevHead = nullptr;
        ListNode* pNode = pHead;
        ListNode* pPrev = nullptr;
        
        while (pNode != nullptr)
        {
            ListNode* pNext = pNode->next;
            
            if (pNext == nullptr)
                pRevHead = pNode;
            
            pNode->next = pPrev;
            
            pPrev = pNode;
            pNode = pNext;
        }
        return pRevHead;
    }
};
牛客网提交代码

 技术图片 

技术图片
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pNode) {
        
        //1.链表为空 2.只有一个元素 3.递归到链表尾
        if(pNode == nullptr || pNode->next == nullptr)
            return pNode;
         
        //先反转后面的链表,寻找末尾节点
        ListNode* pReverseNode = ReverseList(pNode->next);
         
        //再将当前节点设置为下一节点的后续节点
        pNode->next->next = pNode;
        pNode->next = nullptr;
         
        return pReverseNode;
    }
};
递归实现反转链表

 

以上是关于《剑指offer》第二十四题:反转链表的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer(十四,十五)链表中倒数第k个结点,反转链表

剑指offer(二十三,二十四,二十五)最小的k个数,连续子数组的最大和,链表中环的入口节点

剑指offer系列刷题第二篇——从尾到头打印链表和反转链表

剑指offer:反转链表

《剑指offer》第六十四题:求1+2+…+n

《剑指offer》第十四题(剪绳子)