Day3 | 203.移除链表元素 707.设计链表 206.反转链表

61 阅读3分钟

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

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

image.png

如上图,第一个元素6出现时,要使2的next的指向3,因此,对于单链表,应停留在目标节点的上一个节点,但参与条件判断的是cur->next

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummy = new ListNode();  //虚拟头节点
        dummy->next = head;
        ListNode* cur = dummy;
        while(cur->next){
            if(cur->next->val==val){
                cur->next = cur->next->next;
            }
            else cur=cur->next;
        }
        return dummy->next;
    }
};

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

你可以选择使用单链表或者双链表,设计并实现自己的链表。

单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。

如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。

实现 MyLinkedList 类:

  • MyLinkedList() 初始化 MyLinkedList 对象。
  • int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
  • void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
  • void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
  • void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
  • void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

注意索引合法性的判断

注意虚拟头节点_dummy在何处定义,在何处初始化

class MyLinkedList {

public:
    struct LinkedNode{
        int val;
        LinkedNode* next;
        LinkedNode(int v):val(v),next(nullptr){}
    };


    MyLinkedList() {
        _dummy = new LinkedNode(0);
        _size = 0;
    }
    
    int get(int index) {
        if(index>(_size-1)||index<0){
            return -1;
        }

        LinkedNode* cur = _dummy;
        for(int i = 0;i<=index;i++){
            cur = cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
        LinkedNode* newhead = new LinkedNode(val);
        newhead->next = _dummy->next;
        _dummy->next = newhead;
        _size++;
    }
    
    void addAtTail(int val) {
        LinkedNode* cur = _dummy;
        for(int i = 0;i<_size;i++){
            cur = cur->next;
        }
        LinkedNode* newtail = new LinkedNode(val);
        cur->next = newtail;
        _size++;
    }
    
    void addAtIndex(int index, int val) {
        if(index>_size) return;
        if(index<0) index = 0;
        LinkedNode* cur = _dummy;
        for(int i =0 ;i<index;i++){
            cur = cur->next;
        }
        LinkedNode* add = new LinkedNode(val);
        add->next = cur->next;
        cur->next = add;
        _size++;
    }
    
    void deleteAtIndex(int index) {
        if(index<0||index>_size-1){
            return;
        }
        LinkedNode* cur = _dummy;
        for(int i =0 ;i<index;i++){
            cur = cur->next;
        }
        if(index == _size-1){
            cur->next = nullptr;
        }
        else cur->next = cur->next->next;
        _size--;
    }
private:
    int _size; //大小
    LinkedNode* _dummy;//虚拟头节点

};

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

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = nullptr;
        ListNode* cur = head;
        ListNode* temp = nullptr;
        //pre在cur前一位
        //若cur为空,则pre处于尾结点,循环结束,返回pre
        while(cur){
            temp = cur->next;  //存储下一个结点的地址
            cur->next = pre;   //让当前结点的next指向pre
            pre = cur;         //pre 更新为 cur
            cur = temp;        //cur移动到原链表的下一个结点

        }
        return pre;
    }
};