• 剑指offer


    // 面试题23:链表中环的入口结点
    // 题目:一个链表中包含环,如何找出环的入口结点?例如,在图3.8的链表中,
    // 环的入口结点是结点3。

    ListNode* FindFirstNode(ListNode* HeadNode)
    {
        if(!HeadNode)
            return nullptr;
        ListNode* FastNode = HeadNode;
        ListNode* SlowNode = HeadNode;
        while(FastNode&(FastNode->NextPoint))
        {
            SlowNode = SlowNode->NextPoint;
            FastNode = SlowNode->NextPoint;
            if(FastNode == SlowNode)
            {
                SlowNode = HeadNode;
                while(FastNode != SlowNode)
                {
                    FastNode = FastNode->NextPoint;
                    SlowNode = SlowNode->NextPoint;
                }
                return SlowNode;
            }
        }
        return nullptr;
    }


    //找到链表中环形链表的入口点
    ListNode* FindTheFirstNode(ListNode* Node)
    {
        if(Node ==nullptr)
            return nullptr;
        ListNode* Fastp = Node;
        ListNode  Slowp = Node;
        while((Fastp!= Slowp)&(Fastp!=nullptr))
        {
            Fastp = Fastp->NextPoint->NextPoint;
            Slowp = Slowp->NextPoint;
        }
        Slowp =Node;
        while(SLowp != Fastp)
        {
            Slowp = Slowp->NextPoint;
            Fastp = Fastp->NextPoint;
        }
        return slowp;
    }
    

      // 面试题22:链表中倒数第k个结点
    // 题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,
    // 本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,
    // 从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是
    // 值为4的结点。

    #include <cstdio>
    #include "..UtilitiesList.h"
    
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
    {
        if(pListHead == nullptr || k == 0)
            return nullptr;
    
        ListNode *pAhead = pListHead;
        ListNode *pBehind = nullptr;
    
        for(unsigned int i = 0; i < k - 1; ++ i)
        {
            if(pAhead->m_pNext != nullptr)
                pAhead = pAhead->m_pNext;
            else
            {
                return nullptr;
            }
        }
    
        pBehind = pListHead;
        while(pAhead->m_pNext != nullptr)
        {
            pAhead = pAhead->m_pNext;
            pBehind = pBehind->m_pNext;
        }
    
        return pBehind;
    }
    
    // ====================测试代码====================
    // 测试要找的结点在链表中间
    void Test1()
    {
        printf("=====Test1 starts:=====
    ");
        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);
    
        printf("expected result: 4.
    ");
        ListNode* pNode = FindKthToTail(pNode1, 2);
        PrintListNode(pNode);
    
        DestroyList(pNode1);
    }
    
    // 测试要找的结点是链表的尾结点
    void Test2()
    {
        printf("=====Test2 starts:=====
    ");
        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);
    
        printf("expected result: 5.
    ");
        ListNode* pNode = FindKthToTail(pNode1, 1);
        PrintListNode(pNode);
    
        DestroyList(pNode1);
    }
    
    // 测试要找的结点是链表的头结点
    void Test3()
    {
        printf("=====Test3 starts:=====
    ");
        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);
    
        printf("expected result: 1.
    ");
        ListNode* pNode = FindKthToTail(pNode1, 5);
        PrintListNode(pNode);
    
        DestroyList(pNode1);
    }
    
    // 测试空链表
    void Test4()
    {
        printf("=====Test4 starts:=====
    ");
        printf("expected result: nullptr.
    ");
        ListNode* pNode = FindKthToTail(nullptr, 100);
        PrintListNode(pNode);
    }
    
    // 测试输入的第二个参数大于链表的结点总数
    void Test5()
    {
        printf("=====Test5 starts:=====
    ");
        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);
    
        printf("expected result: nullptr.
    ");
        ListNode* pNode = FindKthToTail(pNode1, 6);
        PrintListNode(pNode);
    
        DestroyList(pNode1);
    }
    
    // 测试输入的第二个参数为0
    void Test6()
    {
        printf("=====Test6 starts:=====
    ");
        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);
    
        printf("expected result: nullptr.
    ");
        ListNode* pNode = FindKthToTail(pNode1, 0);
        PrintListNode(pNode);
    
        DestroyList(pNode1);
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
    
        return 0;
    }

     // 面试题52:两个链表的第一个公共结点
    // 题目:输入两个链表,找出它们的第一个公共结点。

    #include <cstdio>
    #include "..UtilitiesList.h"
    
    unsigned int GetListLength(ListNode* pHead);
    
    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 != nullptr) &&
            (pListHeadShort != nullptr) &&
            (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 != nullptr)
        {
            ++nLength;
            pNode = pNode->m_pNext;
        }
    
        return nLength;
    }
    
    // ====================测试代码====================
    void DestroyNode(ListNode* pNode);
    
    void Test(char* testName, ListNode* pHead1, ListNode* pHead2, ListNode* pExpected)
    {
        if(testName != nullptr)
            printf("%s begins: ", testName);
    
        ListNode* pResult = FindFirstCommonNode(pHead1, pHead2);
        if(pResult == pExpected)
            printf("Passed.
    ");
        else
            printf("Failed.
    ");
    }
    
    // 第一个公共结点在链表中间
    // 1 - 2 - 3 
    //            6 - 7
    //     4 - 5 /
    void Test1()
    {
        ListNode* pNode1 = CreateListNode(1);
        ListNode* pNode2 = CreateListNode(2);
        ListNode* pNode3 = CreateListNode(3);
        ListNode* pNode4 = CreateListNode(4);
        ListNode* pNode5 = CreateListNode(5);
        ListNode* pNode6 = CreateListNode(6);
        ListNode* pNode7 = CreateListNode(7);
    
        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode6);
        ConnectListNodes(pNode4, pNode5);
        ConnectListNodes(pNode5, pNode6);
        ConnectListNodes(pNode6, pNode7);
    
        Test("Test1", pNode1, pNode4, pNode6);
    
        DestroyNode(pNode1);
        DestroyNode(pNode2);
        DestroyNode(pNode3);
        DestroyNode(pNode4);
        DestroyNode(pNode5);
        DestroyNode(pNode6);
        DestroyNode(pNode7);
    }
    
    // 没有公共结点
    // 1 - 2 - 3 - 4
    //            
    // 5 - 6 - 7
    void Test2()
    {
        ListNode* pNode1 = CreateListNode(1);
        ListNode* pNode2 = CreateListNode(2);
        ListNode* pNode3 = CreateListNode(3);
        ListNode* pNode4 = CreateListNode(4);
        ListNode* pNode5 = CreateListNode(5);
        ListNode* pNode6 = CreateListNode(6);
        ListNode* pNode7 = CreateListNode(7);
    
        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode4);
        ConnectListNodes(pNode5, pNode6);
        ConnectListNodes(pNode6, pNode7);
    
        Test("Test2", pNode1, pNode5, nullptr);
    
        DestroyList(pNode1);
        DestroyList(pNode5);
    }
    
    // 公共结点是最后一个结点
    // 1 - 2 - 3 - 4 
    //                7
    //         5 - 6 /
    void Test3()
    {
        ListNode* pNode1 = CreateListNode(1);
        ListNode* pNode2 = CreateListNode(2);
        ListNode* pNode3 = CreateListNode(3);
        ListNode* pNode4 = CreateListNode(4);
        ListNode* pNode5 = CreateListNode(5);
        ListNode* pNode6 = CreateListNode(6);
        ListNode* pNode7 = CreateListNode(7);
    
        ConnectListNodes(pNode1, pNode2);
        ConnectListNodes(pNode2, pNode3);
        ConnectListNodes(pNode3, pNode4);
        ConnectListNodes(pNode4, pNode7);
        ConnectListNodes(pNode5, pNode6);
        ConnectListNodes(pNode6, pNode7);
    
        Test("Test3", pNode1, pNode5, pNode7);
    
        DestroyNode(pNode1);
        DestroyNode(pNode2);
        DestroyNode(pNode3);
        DestroyNode(pNode4);
        DestroyNode(pNode5);
        DestroyNode(pNode6);
        DestroyNode(pNode7);
    }
    
    // 公共结点是第一个结点
    // 1 - 2 - 3 - 4 - 5
    // 两个链表完全重合   
    void Test4()
    {
        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);
    
        Test("Test4", pNode1, pNode1, pNode1);
    
        DestroyList(pNode1);
    }
    
    // 输入的两个链表有一个空链表
    void Test5()
    {
        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);
    
        Test("Test5", nullptr, pNode1, nullptr);
    
        DestroyList(pNode1);
    }
    
    // 输入的两个链表有一个空链表
    void Test6()
    {
        Test("Test6", nullptr, nullptr, nullptr);
    }
    
    void DestroyNode(ListNode* pNode)
    {
        delete pNode;
        pNode = nullptr;
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
    
        return 0;
    }
    

     // 面试题51:数组中的逆序对
    // 题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组
    // 成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

     

    #include <cstdio>
    
    int InversePairsCore(int* data, int* copy, int start, int end);
    
    int InversePairs(int* data, int length)
    {
        if(data == nullptr || length < 0)
            return 0;
    
        int* copy = new int[length];
        for(int i = 0; i < length; ++i)
            copy[i] = data[i];
    
        int count = InversePairsCore(data, copy, 0, length - 1);
        delete[] copy;
    
        return count;
    }
    
    int InversePairsCore(int* data, int* copy, int start, int end)
    {
        if(start == end)
        {
            copy[start] = data[start];
            return 0;
        }
    
        int length = (end - start) / 2;
    
        int left = InversePairsCore(copy, data, start, start + length);
        int right = InversePairsCore(copy, data, start + length + 1, end);
    
        // i初始化为前半段最后一个数字的下标
        int i = start + length;
        // j初始化为后半段最后一个数字的下标
        int j = end;
        int indexCopy = end;
        int count = 0;
        while(i >= start && j >= start + length + 1)
        {
            if(data[i] > data[j])
            {
                copy[indexCopy--] = data[i--];
                count += j - start - length;
            }
            else
            {
                copy[indexCopy--] = data[j--];
            }
        }
    
        for(; i >= start; --i)
            copy[indexCopy--] = data[i];
    
        for(; j >= start + length + 1; --j)
            copy[indexCopy--] = data[j];
    
        return left + right + count;
    }
    
    // ====================测试代码====================
    void Test(char* testName, int* data, int length, int expected)
    {
        if(testName != nullptr)
            printf("%s begins: ", testName);
    
        if(InversePairs(data, length) == expected)
            printf("Passed.
    ");
        else
            printf("Failed.
    ");
    }
    
    void Test1()
    {
        int data[] = { 1, 2, 3, 4, 7, 6, 5 };
        int expected = 3;
    
        Test("Test1", data, sizeof(data) / sizeof(int), expected);
    }
    
    // 递减排序数组
    void Test2()
    {
        int data[] = { 6, 5, 4, 3, 2, 1 };
        int expected = 15;
    
        Test("Test2", data, sizeof(data) / sizeof(int), expected);
    }
    
    // 递增排序数组
    void Test3()
    {
        int data[] = { 1, 2, 3, 4, 5, 6 };
        int expected = 0;
    
        Test("Test3", data, sizeof(data) / sizeof(int), expected);
    }
    
    // 数组中只有一个数字
    void Test4()
    {
        int data[] = { 1 };
        int expected = 0;
    
        Test("Test4", data, sizeof(data) / sizeof(int), expected);
    }
    
    
    // 数组中只有两个数字,递增排序
    void Test5()
    {
        int data[] = { 1, 2 };
        int expected = 0;
    
        Test("Test5", data, sizeof(data) / sizeof(int), expected);
    }
    
    // 数组中只有两个数字,递减排序
    void Test6()
    {
        int data[] = { 2, 1 };
        int expected = 1;
    
        Test("Test6", data, sizeof(data) / sizeof(int), expected);
    }
    
    // 数组中有相等的数字
    void Test7()
    {
        int data[] = { 1, 2, 1, 2, 1 };
        int expected = 3;
    
        Test("Test7", data, sizeof(data) / sizeof(int), expected);
    }
    
    void Test8()
    {
        int expected = 0;
    
        Test("Test8", nullptr, 0, expected);
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
        Test6();
        Test7();
        Test8();
    
        return 0;
    }
    

      

  • 相关阅读:
    [SQL Server] 数据库日志文件自动增长导致连接超时的分析
    Visual Studio 2003/Visual Studio 2005常用快捷键(快捷方式)
    設置RichTextBox控件中選中的部分的文字突顯
    電功率單位
    一名25岁的董事长给大学生的18条忠告
    計算機端口
    學習使用Directionary與Hastable
    VS .NET如何切換環境
    VS .NET(C#)如何動態創建控件
    VS .NET(C#)測試程序記錄時間方法
  • 原文地址:https://www.cnblogs.com/hai5111/p/11423633.html
Copyright © 2020-2023  润新知