zoukankan      html  css  js  c++  java
  • 链表操作

    1. 找到链表的中间节点

    思路:用两个指针,初始时都指向链表头,然后一个每次往前走一步,另一个每次往前走两步,走两步的指针走到尾时,走一步的指针的位置即为链表的中间位置

        Node* findMiddleNode(Node* pHead) {
            if (pHead == nullptr) {
                return(pHead);
            }
            if (pHead->next == nullptr) {
                return(pHead);
            }
            Node *pSlow = pHead;
            Node *pFast = pHead;
    
            while (pFast->next != nullptr && pFast->next->next!=nullptr) {
                pSlow = pSlow->next;
                pFast = pFast->next->next;
            }
    
            return(pSlow);
        }
    View Code

    2. 找到倒数第K个节点

    思路:设置两个指针,让其中一个指针先走K步,然后两个指针等速往前走,先走的指针走到尾时,后走指针的位置即为倒数第K个节点

        Node* findReverseKNode(Node* pHead, int k) {
            Node* kNode = nullptr;
            Node* p = pHead;
    
            for (int i = 0; i < k-1; i++) {
                if (p == nullptr) {
                    return(nullptr);
                }
                p = p->next;
            }
    
            kNode = pHead;
            while (p != nullptr) {
                p = p->next;
                kNode = kNode->next;
            }
    
            return(kNode);
        }
    View Code

    3. 链表倒转

    思路:假设p1->p2->p3,倒转p1->p2的时候,需要记录p3

        Node* reverseList(Node* pHead) {
            if (pHead == nullptr || pHead->next == nullptr) {
                return(nullptr);
            }
    
            Node* p = pHead;
            Node* pNext = p->next;
            while (pNext != nullptr) {
                Node *pNextNext = pNext->next;
                pNext->next = p;
                p = pNext;
                pNext = pNextNext;
            }
    
            pHead->next = nullptr;
            pHead = p;
            return(pHead);
        }
    View Code

    4. 找到两个链表的交叉点

    思路:如果两个链表交叉,则可以想象两个链表构成Y形,只是Y的分叉部分不一样长,所以解法为先求出两个链表的长度l1和l2,然后求差值|l1-l2|,设置两个指针分别指向两个链表头,让指向长链表的指针先走|l1-l2|步,然后两个指针再一起走,判断是否相等

        Node* getCrossNode(Node* pHead1, Node* pHead2) {
            Node* p1 = pHead1;
            Node* p2 = pHead2;
            if (p1 == nullptr || p2 == nullptr) {
                return(nullptr);
            }
    
            int l1 = 0;
            while (p1 != nullptr) {
                l1++;
                p1 = p1->next;
            }
    
            int l2 = 0;
            while (p2 != nullptr) {
                l2++;
                p2 = p2->next;
            }
    
            p1 = pHead1;
            p2 = pHead2;
            if (l2 > l1) {
                for (int i = 0; i < (l2 - l1); i++) {
                    p2 = p2->next;
                }
            }
            else if (l1 > l2) {
                for (int i = 0; i < (l1 - l2); i++) {
                    p1 = p1->next;
                }
            }
    
            while (p1 != nullptr && p2 != nullptr && p1 != p2) {
                p1 = p1->next;
                p2 = p2->next;
            }
    
            if (p1 == p2) {
                return(p1);
            }
            else {
                return(nullptr);
            }
        }
    View Code

    5. 判断是否存在环

    思路:设置两个指针,同时指向表头,一个每次往前走一步,另一个走两步,如果两个指针相遇,即存在环

        bool doesContainLoop(Node* pHead) {
            if (pHead == nullptr || pHead->next == nullptr) {
                return(false);
            }
    
            Node* pSlow = pHead;
            Node* pFast = pHead;
            while (pFast != nullptr && pFast->next != nullptr && pSlow != pFast) {
                pSlow = pSlow->next;
                pFast = pFast->next->next;
            }
    
            if (pSlow == pFast) {
                return(true);
            }
            else {
                return(false);
            }
        }
    View Code

    6. 求环的起点

    思路:

    假设两个指针,在Z点相遇,相遇时慢的走了m圈,快的走了n圈,则(a+b+m*r)*2=a+b+n*r,可以推导出a=(n-2m)*r-b=(n-2m-1)*r+r-b=(n-2m-1)*r+c,所以可以设置两个指针,一个从表头X点开始走,另一个从相遇点Z开始走,两个指针相遇的位置即为环的起点

        Node* getLoopOrigin(Node* pHead) {
            if (pHead == nullptr || pHead->next == nullptr) {
                return(nullptr);
            }
    
            Node* pSlow = pHead;
            Node* pFast = pHead;
            while (pFast != nullptr && pFast->next != nullptr && pSlow != pFast) {
                pSlow = pSlow->next;
                pFast = pFast->next->next;
            }
    
            if (pSlow != pFast) {
                return(nullptr);
            }
    
            Node* p = pHead;
            while (p != pSlow) {
                p = p->next;
                pSlow = pSlow->next;
            }
    
            return(p);
        }
    View Code

    7. 求环的长度

    思路:让两个指针都从相遇点开始走,步速为2的指针和步速为1的指针再次相遇时,步速为1的指针所走的长度即为环的长度

        int getLoopLength(Node* pHead) {
            if (pHead == nullptr || pHead->next == nullptr) {
                return(0);
            }
    
            Node* pSlow = pHead;
            Node* pFast = pHead;
            while (pFast != nullptr && pFast->next != nullptr && pSlow != pFast) {
                pSlow = pSlow->next;
                pFast = pFast->next->next;
            }
    
            if (pSlow != pFast) {
                return(0);
            }
            
            int loopLen = 0;
            pSlow = pSlow->next;
            pFast = pFast->next->next;
            while (pSlow != pFast) {
                loopLen++;
                pSlow = pSlow->next;
                pFast = pFast->next->next;
            }
            loopLen++;
            return(loopLen)
        }
    View Code

    8. 求有环链表的长度

    思路:6求出了环的起点,可以得出无环部分的长度,加上7的环的长度,即为有环链表的长度

  • 相关阅读:
    跨浏览器的事件处理程序
    开发技术文档汇总
    JVM知识树
    JDK1.8新特性(一)
    CAS
    Redis集群之修改节点IP
    阿里云服务器 发送邮箱 STMP 25端口 465端口问题 Javamail 25被禁用
    日志log4j到Logback的使用(主要是Logback)
    ThreadLocal原理和 java类全局静态变量在多线程中数据混乱问题
    SpringMVC拦截器拦截页面(坑)
  • 原文地址:https://www.cnblogs.com/guo-xiang/p/10082028.html
Copyright © 2011-2022 走看看