day03 链表part1—移除链表元素、设计链表、翻转链表

这是跟Carl学习《代码随想录》的第三天,主要开始练习链表的操作,之前这种数据结构用的比较少,可能会相对困难一点,今天主要是如何创建链表以及如何实现链表的增删改查。

注意:链表的基础操作还是非常重要的,后续需要重点练习。

今日任务

链表理论基础
203.移除链表元素
707.设计链表
206.反转链表
一、 链表理论基础
建议: 了解一下链接基础,以及链表和数组的区别

文章链接: https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

主要掌握如何创建一个链表的结构体,在Leetcode中一般都会默认生成好:

// 单链表
struct ListNode {
    int val;  // 节点上存储的元素
    ListNode *next;  // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {}  // 节点的构造函数
};

二、 203.移除链表元素
建议: 本题最关键是要理解 虚拟头结点的使用技巧,这个对链表题目很重要。
Leetcode题目:203.移除链表元素
题目链接/文章讲解/视频讲解: https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A8%E5%85%83%E7%B4%A0.html

本题较为简单,主要学习如何删除节点:

有以下注意事项:
(1)不可以使用头结点指针进行遍历,需要新创建一个遍历指针,通常定义为cur;
(2)结束的时候需要重新定义回头指针,即head = dummyNode -> 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) {
        ListNode *dummyNode = new ListNode();
        dummyNode -> next = head;
        ListNode *cur = dummyNode;
        while(cur->next != NULL){
            if(cur->next->val == val){
                ListNode *tmp = cur -> next;
                cur->next = cur->next->next;
                delete tmp;
            }else{
                cur = cur->next;
            }
        }
        head = dummyNode -> next;
        delete dummyNode;
        return head;
    }
};


三、707.设计链表
建议: 这是一道考察 链表综合操作的题目,不算容易,可以练一练 使用虚拟头结点
LeetCode题目:707.设计链表
题目链接/文章讲解/视频讲解: https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html

本题主要实现链表的增删改查,而且要注意索引是从0 开始的,然后类中的成员变量为虚拟头结点和链表的数量大小。然后在插入某一个节点时,要先把后面的搭好,然后再搭前面的。


class MyLinkedList {

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

    MyLinkedList() {
        dummyNode = new LinkNode(0);
        size = 0;
    }
    
    int get(int index) {
        LinkNode *cur = dummyNode -> next;
        if(index < 0 || index > size - 1){
            return -1;
        }else{
            while(index--){
                cur = cur -> next;
            }
            return cur->val;
        }
    }
    
    void addAtHead(int val) {
        LinkNode *headNode = new LinkNode(val);
        headNode -> next  = dummyNode -> next;
        dummyNode -> next = headNode;
        size++;
    }
    
    void addAtTail(int val) {
        LinkNode *tailNode = new LinkNode(val);
        LinkNode *cur = dummyNode;
        while(cur -> next != nullptr){
            cur = cur->next;
        }
        cur -> next = tailNode;
        size++;
    }
    

    void addAtIndex(int index, int val) {
        if(index > size) return;
        if(index < 0) index = 0; 
        LinkNode *newNode = new LinkNode(val);
        LinkNode* cur = dummyNode;
        while(index--){
            cur = cur->next;
        }
        newNode -> next = cur -> next;
        cur -> next = newNode;
        size++;
    }
    
    void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        LinkNode *cur = dummyNode;
        LinkNode *tmp;
        while(index--){
            cur = cur -> next;
        }
        tmp = cur -> next;
        cur -> next = cur->next->next;
        delete tmp;
        tmp = nullptr;
        size--;
    }
private:
    LinkNode *dummyNode;
    int size;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */


四、206.反转链表
建议先看视频讲解,视频讲解中对 反转链表需要注意的点讲的很清晰了,看完之后大家的疑惑基本都解决了。
Leetcode题目:206.反转链表
题目链接/文章讲解/视频讲解: https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html

解决思路双指针法:


/**
 * 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) {
        ListNode *pre, *cur, *temp;
        pre = NULL;
        cur = head;
        while(cur != NULL){
            temp = cur -> next;
            cur -> next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
};
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值