LC203 移除链表元素

203. 移除链表元素 - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if (!head) return head;
        // 单指针,提前预判下个节点是不是目标值,之后做跨越连接,删除
        // 注意:这里不能这么写 VHeader = head;
        // 针对这个测试用例[7,7,7,7], val = 7
        ListNode* VHeader = new ListNode(-1,head);
        ListNode* cur = VHeader;
        ListNode* tem = nullptr;
        while (cur->next)
        {
            if (cur->next->val == val)
            {
                tem = cur->next;
                cur->next = cur->next->next;
                delete tem;
            }
            else cur = cur->next;
        }
        // 针对这个测试用例[7,7,7,7], val = 7
        head = VHeader->next;
        delete VHeader;
        return head;
    }
};

LC707 设计链表

707. 设计链表 - 力扣(LeetCode)

这道题描述给人挖了个坑,需要仔细看题目。

  • get(int index)/deleteAtIndex(int index) 下标从0开始数到第index个

  • addAtIndex(int index, int val) 下标从1开始数到第index个

class MyLinkedList {
public:
    struct LinkNode
    {
        int val = -1;
        LinkNode* next = nullptr;
        LinkNode(int v) : val(v) {}
    };

    MyLinkedList() {
        Vhader = new LinkNode(-1);
    }
    // index 按数组下标 0 ..k.. n 的第 k个
    int get(int index) {
        if (!Vhader->next) return -1;
        else if (index >= _size) return -1;
        tem = Vhader->next;
        while (index--)
            tem = tem->next;
        return tem->val;
    }
         // index 按日常计数顺序 1 ..k.. n 的第 k个(英国从0...n开始数例外 - 雾 -)
    void addAtIndex(int index, int val) {
        if (index > _size) return ;
        tem = Vhader;
        LinkNode* old = nullptr;
        while (index--)
            tem = tem->next;
        old = tem->next;
        tem->next = new LinkNode(val);
        tem->next->next = old;
        _size++;
    }
     // 同 index 按数组下标 0 ..k.. n 的第 k个
    void deleteAtIndex(int index) {
        if (index >= _size) return;
        tem = Vhader;
        LinkNode* old = nullptr;
        while (index--)
            tem = tem->next;
        old = tem->next->next;
        delete tem->next;
        tem->next = old;
        --_size;
    }

    void addAtHead(int val) {
        tem = Vhader->next;
        Vhader->next = new LinkNode(val);
        Vhader->next->next = tem;
        _size++;
    }

    void addAtTail(int val) {
        tem = Vhader;
        while (tem->next) tem = tem->next;
        tem->next = new LinkNode(val);
        _size++;
    }
private:
    LinkNode* Vhader = nullptr;
    LinkNode* tem = nullptr;
    int _size = 0;
};

LC206 反转链表

206. 反转链表 - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (!head || !head->next) return head;
        ListNode* cur = nullptr;
        ListNode* pre = head;
        ListNode* tem = nullptr;
        while(pre)
        {
            tem = pre->next;
            pre->next = cur;
            cur = pre;
            pre = tem; // 注意这里
        }
        return cur;
    }
};

LC24 两两交换链表中的节点

24. 两两交换链表中的节点 - 力扣(LeetCode)

  • 脑筋急转弯,不要做两节点得指针指向,直接互换节点中的值,这样写立马不抽象...

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* VHead = new ListNode(-1,head);
        ListNode* cur = VHead;
        int tem;
        // 其实不用交换指针,交换节点中的值就好(脑筋急转弯),交换两节点指针指向操作繁琐
        while (cur->next && cur->next->next)
        {
            tem = cur->next->val; //备份下个节点得值
            cur->next->val = cur->next->next->val; // 当前节点得下个节点的值覆盖 为下下个结点的值
            cur->next->next->val = tem;
            cur = cur->next->next; // 跳到交换值得第二节点,下次回做回直接看下一个节点和下下个节点,并交换
        }
        return head;
    }
};

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

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* VHead = new ListNode(-1,head);
        ListNode* cur = VHead;
        ListNode* pre = head;
        while(n -- && pre) pre = pre->next;
        while(pre)
        {
            pre = pre->next;
            cur = cur->next;
        }
        ListNode* tem = cur->next;
        cur->next = cur->next->next;
        delete tem;
        return VHead->next;
    }
};

LC 链表相交

面试题 02.07. 链表相交 - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        // 第一次遍历得到两链表长度(不管是否相交)
        // 重置两链表遍历指针,计算出两链表相差几个节点数(也就是长的比短的多几个节点) - delta
        // 让长的先走delta步(delta = |lenA - lenB|)
        // 之后两指针同时向前移动,相交则回地址相同(curA == curB) 返回ture,否则其中一个遍历指针遍历到末尾则认为没有相交点.
        if (!headA || !headB) return nullptr;
        int lenA = 1, lenB = 1;
        ListNode* curA = headA;
        ListNode* curB = headB;
        while (curA || curB)
        {
            if (curA){
                curA = curA->next;
                lenA ++;
            }
            if (curB)
            {
                curB = curB->next;
                lenB ++;
            }
        }
        curA = headA;
        curB = headB;
        // ListNode*& 指针引用, C++ 11新特性,但是这里*和& 必须写一起,且 必须和类型名紧挨 : ListNode*&
        auto f = [](ListNode*& curA, ListNode*& curB, int delta) -> ListNode* /* c++ 11 匿名函数返回值 */ {
            while(delta --) curA = curA->next;
            while(curA && curB)
            {
                if (curA == curB) return curA;
                else
                {
                    curA = curA->next;
                    curB = curB->next;
                }
            }
                return nullptr;
            };
        return lenA > lenB ? f(curA,curB,lenA - lenB) : f(curB,curA,lenB - lenA);
    }
};

LC142 环形链表II

142. 环形链表 II - 力扣(LeetCode)

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *slow = head,*fast = head;
        // 快慢指针,快指针比慢指针多走一步,如果有环,两指针总会相遇
        // 相遇后快指针重置从链表头开始追慢指针,相遇得的地方就是环入口,证明、图解网上搜,图太长...有理论证明的。(定律黎嘅)
        while(fast)
        {
            slow = slow->next;
            if(!fast->next) return nullptr;
            else fast = fast->next->next;
            if (slow == fast)
            {
                fast = head;
                while(slow != fast)
                {
                    slow = slow->next;
                    fast = fast->next;
                }
                return fast;
            }
        }
        return nullptr;
    }
};