• 面试中常见现场编程题(手写)


    struct ListNode
    {
        int value;
        ListNode * next;
        ListNode(int v): value(v),next(NULL){}
    }

    1链表合并

      合并两个递增排序的链表

    ListNode * Merge(ListNode * pHead1,ListNode * pHead2)
    {
        if(pHead1==NULL)
            return pHead2;
        else if(pHead2==NULL)
            return pHead1;
        ListNode * pMerge = NULL;
        if(pHead1->value < pHead2->value)
        {
            pMerge = pHead1;
            pMerge->next = Merge(pHead1->next,pHead2);
        }else
        {
            pMerge = pHead2;
            pMerge->next = Merge(pHead1,pHead2->next);
        }
        return pMerge;
    }

    2 链表相加

      给定两个链表,分别表示两个非负整数。它们的数字逆序存储在链表中,每个结点只存储一个数字,计算两个数字的和,并返回链表头指针

    /*不带头结点*/
    ListNode * Add(ListNode * head1,ListNode * head2)
    {
        ListNode* pSum = NULL;
        ListNode * pTail = NULL;
        ListNode * pCur = NULL;
        int carry = 0;
        int value = 0;
        while(head1 && head2)
        {
            value = carry + head1->value + head2->value;
            carry = value / 10;
            value %= 10;
            pCur = new ListNode(value);
            if(pTail)
            {
                pTail->next = pCur;
                pTail = pCur;
            }else
            {
                pSum = pCur;
                pTail = pCur;
            }
            head1 = head1->next;
            head2 = head2->next;
        }
        ListNode * p = head1 ? head1 : head2;
        while(p)
        {
            value = p->value +carry;
            carry = value / 10;
            value %= 10;
            pCur = new ListNode(value);
            if(pTail)
            {
                pTail->next = pCur;
                pTail = pCur;
            }else
            {
                pSum = pCur;
                pTail = pCur;
            }
            p = p->next;
        }
        if(carry)
        {
            pTail->next = new ListNode(carry);
        }
        return pSum;
    }
    /*带头结点的情况 */
    ListNode * Add(ListNode * head1,ListNode * head2)
    {
        ListNode* pSum = new ListNode(0);
        ListNode * pTail = pSum;
            ListNode * p1 = head1->next;
            ListNode * p2 = head2->next;
        ListNode * pCur = NULL;
        int carry = 0;
        int value = 0;
        while(p1&& p2)
        {
            value = carry + p1->value + p2->value;
            carry = value / 10;
            value %= 10;
            pCur = new ListNode(value);
            
            pTail->next = pCur;
            pTail = pCur;
            
            p1= p1->next;
            p2= p2->next;
        }
        ListNode * p = p1? p1: p2;
        while(p)
        {
            value = p->value +carry;
            carry = value / 10;
            value %= 10;
            pCur = new ListNode(value);
        
            pTail->next = pCur;
            pTail = pCur;
            p = p->next;
        }
        if(carry)
        {
            pTail->next = new ListNode(carry);
        }
        return pSum;
    }    

    3 链表部分翻转

        给定一个链表,翻转该链表从m到n的位置,要求直接翻转而非申请新空间

    如 1->2->3->4->5  m=2,n=4  返回 1->4->3->2->5

    /*带头结点*/
    void Reverse(ListNode * pHead,int from,int to)
    {
        ListNode* pCur = pHead->next;
        int i;
        for(i=0;i<from-1;i++)
        {
            pHead = pCur;
            pCur = pCur->next;
        }
        ListNode* pPre = pCur;
        pCur = pCur->pNext;
        to--;
        ListNode * pNext;
        for(;i<to;i++)
        {
            pNext = pCur->pNext;
            pCur->pNext = pHead->pNext;
            pHead->pNext = pCur;
            pPre->pNext = pNext;
            pCur = pNext;
        }
    }
    /*不用头结点 */
    void Reverse(ListNode ** head,int from,int to)
    {
        if(head == NULL) return;
        ListNode * pCur = *head;
        ListNode * pHead = *head;
        int i;
        for(i = 0; i < from - 1; i++)
        {
            pHead = pCur;
            pCur = pCur->next;
        }
        ListNode * pPre = pCur;
        pCur = pCur->next;
        ListNode * pNext;
        for(; i < to-1; i++)
        {
            pNext = pCur->next;
            pCur->next = pHead->next;
            pHead->next = pCur;
            pPre->next = pNext;
            pCur = pNext;
        }
    }

    4 链表划分(思考快排)

      给定一个链表和一个值x,将链表划分为两部门,使得划分后小于x的节点在前,大于x的结点在后,在这两部分中要保持原链表中的出现顺序

    /*带头结点*/
    void Partition(ListNode * pHead, int pivotkey)
    {
        ListNode * pLeft = new ListNode(0);
        ListNode * pRight = new ListNode(0);
        ListNode * left = pLeft;
        ListNode * right = pRight;
        ListNode * p = pHead->next;
        while(p)
        {
            if(p->value < pivotkey)
            {
                left->next = p;
                left = p;
            }else
            {
                right->next = p;
                right = p;
            }
            p = p->next;
        }
        left->next = pRight->next;
        right->next = NULL:
        pHead->next = pLeft->next;
        delete pLeft;
        delete pRight;
    }

    5 链表环入口

      一个链表中包含环,如何找出环的入口结点

        如图 找到3

    ListNode* MeetingNode(ListNode* pHead)
    {
        if(pHead == NULL)
            return NULL;
    
        ListNode* pSlow = pHead->m_pNext;
        if(pSlow == NULL)
            return NULL;
    
        ListNode* pFast = pSlow->m_pNext;
        while(pFast != NULL && pSlow != NULL)
        {
            if(pFast == pSlow)
                return pFast;
    
            pSlow = pSlow->m_pNext;
    
            pFast = pFast->m_pNext;
            if(pFast != NULL)
                pFast = pFast->m_pNext;
        }
    
        return NULL;
    }
    
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        ListNode* meetingNode = MeetingNode(pHead);
        if(meetingNode == NULL)
            return NULL;
    
        // get the number of nodes in loop
        int nodesInLoop = 1;
        ListNode* pNode1 = meetingNode;
        while(pNode1->m_pNext != meetingNode)
        {
            pNode1 = pNode1->m_pNext;
            ++nodesInLoop;
        }
    
        // move pNode1
        pNode1 = pHead;
        for(int i = 0; i < nodesInLoop; ++i)
            pNode1 = pNode1->m_pNext;
    
        // move pNode1 and pNode2
        ListNode* pNode2 = pHead;
        while(pNode1 != pNode2)
        {
            pNode1 = pNode1->m_pNext;
            pNode2 = pNode2->m_pNext;
        }
    
        return pNode1;
    }

    6 两个链表的第一个公共节点

    ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2)
    {
        // 得到两个链表的长度
        unsigned int nLength1 = GetListLength(pHead1);
        unsigned int nLength2 = GetListLength(pHead2);
        int nLengthDif = nLength1 - nLength2;
     
        ListNode* pListHeadLong = pHead1;
        ListNode* pListHeadShort = pHead2;
        if(nLength2 > nLength1)
        {
            pListHeadLong = pHead2;
            pListHeadShort = pHead1;
            nLengthDif = nLength2 - nLength1;
        }
     
        // 先在长链表上走几步,再同时在两个链表上遍历
        for(int i = 0; i < nLengthDif; ++ i)
            pListHeadLong = pListHeadLong->m_pNext;
     
        while((pListHeadLong != NULL) && 
            (pListHeadShort != NULL) &&
            (pListHeadLong != pListHeadShort))
        {
            pListHeadLong = pListHeadLong->m_pNext;
            pListHeadShort = pListHeadShort->m_pNext;
        }
     
        // 得到第一个公共结点
        ListNode* pFisrtCommonNode = pListHeadLong;
     
        return pFisrtCommonNode;
    }
    
    unsigned int GetListLength(ListNode* pHead)
    {
        unsigned int nLength = 0;
        ListNode* pNode = pHead;
        while(pNode != NULL)
        {
            ++ nLength;
            pNode = pNode->m_pNext;
        }
     
        return nLength;
    }

    7 链表倒数第K个节点

    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
    {
        if(pListHead == NULL || k == 0)
            return NULL;
    
        ListNode *pAhead = pListHead;
        ListNode *pBehind = NULL;
    
        for(unsigned int i = 0; i < k - 1; ++ i)
        {
            if(pAhead->m_pNext != NULL)
                pAhead = pAhead->m_pNext;
            else
            {
                return NULL;
            }
        }
    
        pBehind = pListHead;
        while(pAhead->m_pNext != NULL)
        {
            pAhead = pAhead->m_pNext;
            pBehind = pBehind->m_pNext;
        }
    
        return pBehind;
    }

    8 删除重复节点

     1->2->3->3->4->4->5     变成  1->2->5

    void deleteDuplication(ListNode** pHead)
    {
        if(pHead == NULL || *pHead == NULL)
            return;
            
        ListNode* pPreNode = NULL;
        ListNode* pNode = *pHead;
        while(pNode != NULL)
        {
            ListNode *pNext = pNode->m_pNext;
            bool needDelete = false;
            if(pNext != NULL && pNext->m_nValue == pNode->m_nValue)
                needDelete = true;
    
            if(!needDelete)
            {
                pPreNode = pNode;
                pNode = pNode->m_pNext;
            }
            else
            {
                int value = pNode->m_nValue;    
                ListNode* pToBeDel = pNode;
                while(pToBeDel != NULL && pToBeDel->m_nValue == value)
                {
                    pNext = pToBeDel->m_pNext;
                    
                    delete pToBeDel;
                    pToBeDel = NULL;
                    
                    pToBeDel = pNext;
                }
                
                if(pPreNode == NULL)
                    *pHead = pNext;
                else
                    pPreNode->m_pNext = pNext;
                pNode = pNext;
            }
        }
    }

    思考  

    8中 保留第一个重复的节点  ?

    头插法

    链表头结点的作用  思考

  • 相关阅读:
    未处理的异常 stack overflow
    Largest Rectangle in a Histogram [POJ2559] [单调栈]
    Blocks [POJ3734] [矩阵快速幂]
    Rectangular Covering [POJ2836] [状压DP]
    Arrange the Bulls [POJ2441] [状压DP]
    The Water Bowls [POJ3185] [开关问题]
    Bound Found [POJ2566] [尺取法]
    4 Values whose Sum is 0 [POJ2785] [折半搜索]
    Physics Experiment 弹性碰撞 [POJ3684]
    Fliptile [POJ3279] [开关问题]
  • 原文地址:https://www.cnblogs.com/hlongch/p/5707285.html
Copyright © 2020-2023  润新知