代码随想录第三天 203.移除链表元素 、707.设计链表 、 206.反转链表

203.移除链表元素,需要注意当需要移除的是头节点时需要单独处理,不如直接添加一个虚拟头节点再进行节点移除的操作逻辑上舒服,代码如下,代码复杂度O(n),O(1)。

#include <iostream>
#include <vector>

struct ListNode
{
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

ListNode *removeElements(ListNode *head, int val)
{
    // 创建一个哨兵节点,它的 next 指向头节点
    ListNode *dummy = new ListNode(0);
    dummy->next = head;

    // 使用 current 指针遍历链表
    ListNode *current = dummy;
    while (current->next != nullptr)
    {
        if (current->next->val == val)
        {
            // 如果当前节点的下一个节点需要被删除
            ListNode *toDelete = current->next;
            current->next = current->next->next;
            delete toDelete; // 释放被删除节点的内存
        }
        else
        {
            // 否则,继续向下遍历
            current = current->next;
        }
    }

    // 新的头节点在哨兵节点的 next
    ListNode *newHead = dummy->next;
    delete dummy; // 释放哨兵节点
    return newHead;
}

// 用于创建链表的辅助函数
ListNode *createList(const std::vector<int> &values)
{
    ListNode *dummy = new ListNode(0);
    ListNode *tail = dummy;
    for (int val : values)
    {
        tail->next = new ListNode(val);
        tail = tail->next;
    }
    return dummy->next;
}

// 用于打印链表的辅助函数
void printList(ListNode *head)
{
    while (head != nullptr)
    {
        std::cout << head->val << " ";
        head = head->next;
    }
    std::cout << std::endl;
}

int main()
{
    ListNode *list1 = createList({1, 2, 6, 3, 4, 5, 6});
    ListNode *result1 = removeElements(list1, 6);
    printList(result1); // 应输出 1, 2, 3, 4, 5

    ListNode *list2 = createList({});
    ListNode *result2 = removeElements(list2, 1);
    printList(result2); // 应输出空

    ListNode *list3 = createList({7, 7, 7, 7});
    ListNode *result3 = removeElements(list3, 7);
    printList(result3); // 应输出空

    return 0;
}

707.设计链表,链表基本功练习

#include <iostream>
#include <vector>

class MyLinkedList
{
private:
    struct ListNode
    {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(nullptr) {}
    };
    ListNode *head;
    int size;

public:
    MyLinkedList() : head(nullptr), size(0) {}

    ~MyLinkedList()
    {
        ListNode *current = head;
        while (current != nullptr)
        {
            ListNode *next = current->next;
            delete current;
            current = next;
        }
    }

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

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

    void addAtTail(int val)
    {
        ListNode *newNode = new ListNode(val);
        if (head == nullptr)
        {
            head = newNode;
        }
        else
        {
            ListNode *current = head;
            while (current->next != nullptr)
            {
                current = current->next;
            }
            current->next = newNode;
        }
        size++;
    }

    void addAtIndex(int index, int val)
    {
        if (index > size)
            return;
        if (index <= 0)
        {
            addAtHead(val);
        }
        else if (index == size)
        {
            addAtTail(val);
        }
        else
        {
            ListNode *current = head;
            for (int i = 0; i < index - 1; i++)
            {
                current = current->next;
            }
            ListNode *newNode = new ListNode(val);
            newNode->next = current->next;
            current->next = newNode;
            size++;
        }
    }

    void deleteAtIndex(int index)
    {
        if (index < 0 || index >= size)
            return;
        ListNode *current = head;
        if (index == 0)
        {
            head = head->next;
            delete current;
        }
        else
        {
            for (int i = 0; i < index - 1; i++)
            {
                current = current->next;
            }
            ListNode *toDelete = current->next;
            current->next = toDelete->next;
            delete toDelete;
        }
        size--;
    }
};

int main()
{
    MyLinkedList linkedList;
    linkedList.addAtHead(1);
    linkedList.addAtTail(3);
    linkedList.addAtIndex(1, 2);                 // 链表变为1-> 2-> 3
    std::cout << linkedList.get(1) << std::endl; // 返回2
    linkedList.deleteAtIndex(1);                 // 现在链表是1-> 3
    std::cout << linkedList.get(1) << std::endl; // 返回3
    return 0;
}

206反转链表,双指针大法好

#include <iostream>
#include <vector>

struct ListNode
{
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

ListNode *reverseList(ListNode *head)
{
    ListNode *prev = nullptr;
    ListNode *curr = head;
    while (curr != nullptr)
    {
        ListNode *next_temp = curr->next; // 保存当前节点的下一个节点
        curr->next = prev;                // 反转当前节点的指向
        prev = curr;                      // 更新prev为当前节点
        curr = next_temp;                 // 移动到原链表的下一个节点
    }
    return prev; // 新的头节点
}

// 用于创建链表的辅助函数
ListNode *createList(const std::vector<int> &values)
{
    ListNode *dummy = new ListNode(0);
    ListNode *tail = dummy;
    for (int val : values)
    {
        tail->next = new ListNode(val);
        tail = tail->next;
    }
    return dummy->next;
}

// 用于打印链表的辅助函数
void printList(ListNode *head)
{
    while (head != nullptr)
    {
        std::cout << head->val << " ";
        head = head->next;
    }
    std::cout << std::endl;
}

int main()
{
    ListNode *list = createList({1, 2, 3, 4, 5});
    std::cout << "Original list: ";
    printList(list);

    ListNode *reversedList = reverseList(list);
    std::cout << "Reversed list: ";
    printList(reversedList);

    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值