• 链表类问题


    基础链表题目

    206. 反转链表

    使用双指针法解决链表问题

    19. 删除链表的倒数第N个节点

    用两个指针指向head节点,先让第一个指针走n-1步,然后再让两个指针同时走,直到第一个指针的next为nullptr,此时第二个指针指向的就是要删除的节点。这里为了减少不必要的判断,我们把第二个指针设为二级指针。

    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode* pfirst = head;
            ListNode** psecond = &head;
            for (int i = 1;i < n;++i) {
                pfirst = pfirst->next;
            }
            while (pfirst->next) {
                psecond = &(*psecond)->next;
                pfirst = pfirst->next;
            }
            *psecond = (*psecond)->next;
            return head;
        }
    };
    

    160. 相交链表

    先遍历两个链表获取它们的长度lenA和lenB,然后先让指针ptrA在长链表(假设长链表是A,短链表是B)上走lenA - lenB步,再让指针ptrA和ptrB分别在长链表和短链表上移动,二者相遇时就是交叉点。

    class Solution {
    public:
        ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
            int lenA = getLength(headA);
            int lenB = getLength(headB);
            if (lenA > lenB) {
                for (int i = 0;i < lenA - lenB;++i) {
                    headA = headA->next;
                }
            } else {
                for (int i = 0;i < lenB - lenA;++i) {
                    headB = headB->next;
                }
            }
    
            while (headA && headB) {
                if (headA == headB) {
                    return headA;
                } else {
                    headA = headA->next;
                    headB = headB->next;
                }
            }
            return nullptr;
        }
    private:
        int getLength(ListNode* head) {
            int len = 0;
            while (head) {
                ++len;
                head = head->next;
            }
            return len;
        }
    };
    

    使用二级指针操作链表

    2. 两数相加

    class Solution {
    public:
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            auto p1 = l1;
            auto p2 = l2;
            ListNode* ph = nullptr;
            ListNode** curr = &ph;
            int carry = 0;
            while (p1 || p2) {
                int x = p1 ? p1->val : 0;
                int y = p2 ? p2->val : 0;
                int val = x + y + carry;
                carry = val / 10;
                val = carry ? val - 10 : val;
                *curr = new ListNode(val);
                curr = &(*curr)->next;
                if (p1) p1 = p1->next;
                if (p2) p2 = p2->next;
            }
            if (carry) *curr = new ListNode(1);
            return ph;
        }
    };
    

    LeetCode 21. 合并两个有序链表

    class Solution {
    public:
        ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
            ListNode* head = nullptr;
            ListNode** curr = &head;
            auto p1 = l1;
            auto p2 = l2;
            while (p1 && p2) {
                if (p1->val < p2->val) {
                    *curr = p1, p1 = p1->next;
                } else {
                    *curr = p2, p2 = p2->next;
                }
                curr = &(*curr)->next;
            }
            if (p1) *curr = p1;
            if (p2) *curr = p2;
            return head;
        }
    };
    

    相似题目
    23. 合并K个有序链表
    21题的进阶版,每次迭代,分别合并链表数组中第一个和最后一个链表,当数组中仅剩一个链表时退出,均摊时间复杂度为(O(nlog n))

    148. 排序链表

    重新排列链表

    86. 分隔链表

    class Solution {
    public:
        ListNode* partition(ListNode* head, int x) {
            ListNode* newHead = nullptr;
            ListNode** prev = &newHead;
            for (auto iter = &head; *iter;) {
                if ((*iter)->val < x) {
                    *prev = *iter;
                    prev = &(*prev)->next;
                    *iter = (*iter)->next;
                } else {
                    iter = &(*iter)->next;
                }
            }
            *prev = head;
            return newHead;
        }
    };
    

    相关题目:
    328. 奇偶链表

    链表与其他数据结构的结合

    138. 复制带随机指针的链表

    /*
    // Definition for a Node.
    class Node {
    public:
        int val;
        Node* next;
        Node* random;
        
        Node(int _val) {
            val = _val;
            next = NULL;
            random = NULL;
        }
    };
    */
    class Solution {
    public:
        Node* copyRandomList(Node* head) {
            Node* pHead = head;
    
            while (head) {
                randomMap[head] = new Node(head->val);
                head = head->next;
            }
            
            Node* newHead = randomMap[pHead];
            Node* qHead = newHead;
            while (qHead && pHead) {
                qHead->next = randomMap[pHead->next];
                qHead->random = randomMap[pHead->random];
                pHead = pHead->next;
                qHead = qHead->next;
            }
    
            return newHead;
        }
    private:
        unordered_map<Node*, Node*> randomMap;
    };
    
  • 相关阅读:
    OpenGL---------BMP文件格式
    OpenGL———混合的基本知识
    OpenGL------显示列表
    OpenGL---------光照的基本知识
    OpenGL学习--------动画制作
    OpenGL------三维变换
    OpenGL学习--------颜色的选择
    OpenGL学习-------点、直线、多边形
    Windows X64汇编入门(1)
    x86 x64下调用约定浅析
  • 原文地址:https://www.cnblogs.com/littleorange/p/13353123.html
Copyright © 2020-2023  润新知