剑指offer 链表专题(二)

来源:互联网 发布:c语言char基本用法 编辑:程序博客网 时间:2024/05/10 07:00

专题一介绍了链表以及链表的一些简单的操作,这章专题探究剑指offer里的一些面试题目。

(1)面试题16 P112
输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
法一:递归

ListNode* ReverseList(ListNode* pHead) {    if(pHead==NULL||pHead->next==NULL)         return pHead;    ListNode* pReverse=ReverseList(pHead->next);    pHead->next->next=pHead;    pHead->next=NULL;    return pReverse;

法二:网上看到别人的解法,也是用两个指针记录当前点的前驱和后驱,不过比答案的代码简洁一些

ListNode* ReverseList(ListNode* pHead) {        ListNode* pre = NULL;        ListNode* next = NULL;        while (pHead != NULL)     {                next = pHead->m_pNext;//记录后驱结点                pHead->m_pNext = pre;// 把指针从指向后一个结点改为指向前一个               pre = pHead; //记录前驱结点               pHead = next; //向后一个结点       }        return pre;}

(2)输入一个链表,输出该链表倒数第k个结点
方法一:看到这个题我本能的想到了堆栈,但是这样要遍历两次,不是很高效,还要额外的空间

class Solution {public:    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {        std::stack<ListNode*> nodes;        if(pListHead == NULL || k ==0)//不要忘记k=0的情况            return NULL;        ListNode* pNode = pListHead;        int count = 0;        while (pNode != NULL)        {            nodes.push(pNode);            count ++;            pNode = pNode->next;        }        if (k>count)  //如果k比链表长度大            return NULL;        else        {            for(int i = 1;i<k;i++)                nodes.pop();            return nodes.top();        }    }};

方法二就是按照书中给的答案,设立两个指针去移动

(3)输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。
思路:这也是典型的可以用递归解决的问题

ListNode* Merge(ListNode* pHead1, ListNode* pHead2){    if (pHead1 == NULL)        return pHead2;    if (pHead2 == NULL)        return pHead1;    ListNode* pMergeHead = NULL;    if (pHead1->m_Value < pHead2->m_Value)    {        pMergeHead = pHead1;        pMergeHead->m_pNext = Merge(pHead1->m_pNext,pHead2);    }    else    {        pMergeHead = pHead2;        pMergeHead->m_pNext = Merge(pHead1,pHead2->m_pNext);    }    return pMergeHead;}
0 0
原创粉丝点击