算法训练 Leetcode 203、206、707

发布时间 2023-09-09 00:07:10作者: 烫烫烫汤圆

算法训练 Leetcode 203、206、707

203.移除链表元素

以为头结点是空的,里面只存着下一个结点的地址。

注意空指针检查:p!=NULL;

class Solution
{
public:
    ListNode *removeElements(ListNode *head, int val)
    {
        ListNode *p = head;
        while (p != nullptr && p->next != nullptr)
        {
            if (p->next->val == val)
            {
                ListNode *q = p->next;
                p->next = p->next->next;
                delete q;
            }
            else
                p = p->next;
        }
        if (head != nullptr && head->val == val)
        {
            ListNode *p = head;
            head = head->next;
            delete p;
        }
        return head;
    }
};

707.设计链表

指针总是出错,关键在于

LinkNode* p = poorhead;还是LinkNode* p = poorhead->next;

题解

#include <iostream>
using namespace std;
class MyLinkedList
{

public:
    // 定义链表结构体
    struct LinkNode
    {
        int val;
        LinkNode *next;
        LinkNode(int val) : val(val), next(nullptr) {}
    };

    // 链表初始化
public:
    MyLinkedList()
    {
        poorhead = new LinkNode(0);
        _size = 0;
    }

    // 获取链表中下标为index的节点的值
    int get(int index)
    {
        if (index < 0 || index >= _size)
            return -1;
        LinkNode *p = poorhead->next;
        while (index--)
        {
            p = p->next;
        }
        return p->val;
    }

    // 将值val结点插入到第一个元素之前
    void addAtHead(int val)
    {
        LinkNode *p = new LinkNode(val);
        p->next = poorhead->next;
        poorhead->next = p;
        _size++;
    }

    // 将值val结点追加作为链表最后一个元素*******
    void addAtTail(int val)
    {
        // LinkNode* p = poorhead->next;******
        LinkNode *p = poorhead;
        while (p != nullptr && p->next != nullptr)
        {
            p = p->next;
        }
        // LinkNode* newnode = new LinkNode(val);
        // p ->next = newnode;
        p->next = new LinkNode(val);
        _size++;
    }

    // 将val值结点插入到链表中下表为index的结点之前,如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
    void addAtIndex(int index, int val)
    {
        if (index > _size)
            return;
        if (index < 0)
            index = 0;
        LinkNode *newnode = new LinkNode(val);
        LinkNode *p = poorhead;
        while (index--)
        {
            p = p->next;
        }
        newnode->next = p->next;
        p->next = newnode;
        _size++;
    }

    // 如果下标有效,则删除链表中下标为 index 的节点
    void deleteAtIndex(int index)
    {
        if (index >= 0 && (index - _size) < 0)
        {
            LinkNode *p = poorhead;
            while (index--)
            {
                p = p->next;
            }
            LinkNode *q = p->next;
            p->next = p->next->next;
            delete q;
            q == nullptr;
            _size--;
        };
    }
    void printLinkedList()
    {
        LinkNode *cur = poorhead;
        while (cur->next != nullptr)
        {
            cout << cur->next->val << " ";
            cur = cur->next;
        }
        cout << _size << endl;
    }

private:
    int _size;
    LinkNode *poorhead;
};

int main()
{
    MyLinkedList list;
    list.addAtTail(1);
    list.get(0);

    return 0;
}

// 指针指针指针指针!!!!!

206.反转链表

相对简单,复习了双指针和递归

题解

// 双指针

class Solution
{
public:
    ListNode *reverseList(ListNode *head)
    {
        ListNode *temp;
        ListNode *pre = head;
        ListNode *cur = NULL;
        while (pre)
        {
            temp = pre->next;
            pre->next = cur;
            cur = pre;
            pre = temp;
            ;
        }
        return cur;
    }
};

// 递归
class Solution
{
public:
    ListNode *reverse(ListNode *pre, ListNode *cur)
    {
        if (pre == NULL)
            return cur;
        ListNode *temp = pre->next;
        pre->next = cur;
        return reverse(temp, pre);
    }
    ListNode *reverseList(ListNode *head)
    {
        return reverse(head, NULL);
    }
};

收获

指针!总是无法做对指针的指向选择。