代码随想录算法训练营第三天| 203.移除链表元素 、707.设计链表 、 206.反转链表

文档讲解:双指针(左右指针),滑动窗口

203.移除链表元素

代码随想录题目

要移除链表元素,需要双指针,now指针指向要移除链表元素,next指针指向要移除链表元素的下一个元素。
更新必须按照以下顺序:now->next = next->next;next = now->next;防止会丢失要移除链表元素之后的元素

双指针:

//双指针:左闭右闭
/**
 * 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) {
        while(head != nullptr && head->val == val){
            head = head->next;
        }
        if(head == nullptr) return nullptr;

        ListNode* now = head, *next = head->next;
        while(next != nullptr){
            if(next->val == val){
                now->next = next->next;
                next = now->next;
            }
            else{
                now = now->next;
                next = next->next;
            }
        }
        return head;
    }
};

707.设计链表

代码随想录题目链接

单链表

class MyLinkedList {
public:
    struct ListNode {
        int val;
        ListNode* next;
        ListNode(int x) : val(x), next(NULL) {};
    };
    // 初始化链表
    MyLinkedList() {
        _size = 0;
    }

    int get(int index) {
        ListNode* Cur = head;
        for (int i = 0; i <= index; i++) {
            if (Cur == NULL) return -1;
            if (i == index) return Cur->val;
            Cur = Cur->next;
        }
        return -1;
    }

    void addAtHead(int val) {
        ListNode* NewHead = new ListNode(val);
        NewHead->next = head;
        head = NewHead;
        _size++;
    }

    void addAtTail(int val) {
        ListNode* NewTail = new ListNode(val);
        if (head == NULL)
        {
            head = NewTail;
            _size++;
            return;
        }

        ListNode* Cur = head;
        while (Cur != NULL) {
            if (Cur->next == NULL) {
                Cur->next = NewTail;
                _size++;
                return;
            }
            Cur = Cur->next;
        }
        
    }

    void addAtIndex(int index, int val) {
        ListNode* NewNode = new ListNode(val);
        if (head == NULL)
        {
            head = NewNode;
            _size++;
            return;
        }

        ListNode* Cur = head;
        for (int i = 0; i < index; i++) {
            if (Cur == NULL) return;
            if (i == index - 1) {
                if (Cur->next == NULL) Cur->next = NewNode;
                NewNode->next = Cur->next;
                Cur->next = NewNode;
            }
            Cur = Cur->next;
        }
        _size++;
    }

    void deleteAtIndex(int index) {
        if (head == NULL) return;

        ListNode* Temp;
        if (index == 0) {
            Temp = head;
            head = head->next;
            delete Temp;
            _size--;
            return;
        }

        ListNode* Cur = head;
        for (int i = 0; i < index; i++) {
            if (Cur == NULL) return;
            if (i == index - 1) {
                if (Cur->next == NULL) return;
                Temp = Cur->next;
                Cur->next = Cur->next->next;
                delete Temp;
                _size--;
            }
            Cur = Cur->next;
        }
    }

    // 打印链表
    void printLinkedList() {
        ListNode* cur = head;
        while (cur->next != nullptr) {
            cout << cur->next->val << " ";
            cur = cur->next;
        }
        cout << endl;
    }

private:
    ListNode* head;
    size_t _size;
};

206.反转链表

代码随想录题目链接

反转链表需要使用三指针分别指向连续链接的节点,在前两节点反转时不会丢失第三节点

/**
 * 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 == nullptr) return nullptr;
        ListNode *n1 = head;
        ListNode *n2 = n1->next;
        ListNode *n3;
        while(n2 != nullptr){
            n3 = n2->next;
            n2->next = n1;
            n1 = n2;
            n2 = n3;
        }
        head->next = nullptr;//原头节点的next应该指向空节点
        head = n1;
        return head;
    }
};

收获

滑动窗口:右进左出,左指针如何根据右指针的遍历结果来对数组进行操作
螺旋矩阵:关键是确定每圈的初始位置和每圈的四条边长度,然后坚持循环不变量原则。

你可能感兴趣的:(算法,链表,数据结构)